#!/usr/bin/env python3

import csv
import os
import os.path
import pickle
import pprint
import re
import subprocess
import sys

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow,Flow
from google.auth.transport.requests import Request


SCOPES = ['https://www.googleapis.com/auth/spreadsheets']

gsheetId = '1x290h82sb6EErD37emRuTQL9_E4v8lPEyMyfcei_BGA'


def pformat(*args, **kw):
    return pprint.pformat(*args, width=200, **kw)


def get_service():
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'client_secrets.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    return build('sheets', 'v4', credentials=creds)


def main(argv):
    spice_dir = argv[1]

    assert os.path.exists(spice_dir), spice_dir
    assert os.path.isdir(spice_dir), spice_dir
    cmd = "grep '.include' $(find {} -name *.spice | sort) | sed -e's@/\\([^/]*\\):@,\\1,@' > spice-includes.csv".format(spice_dir)
    print(cmd)
    subprocess.check_call(cmd, shell=True)

    service = get_service()

    # Upload the names2files-b.csv to the sheet
    SHEET_NAME = "Sheet1"

    sheet_metadata = service.spreadsheets().get(spreadsheetId=gsheetId).execute()
    sheets = sheet_metadata.get('sheets', '')
    title2sheetid = {}
    for s in sheets:
        title = s.get("properties", {}).get("title", "Sheet1")
        sheet_id = s.get("properties", {}).get("sheetId", 0)
        title2sheetid[title] = sheet_id

    assert SHEET_NAME in title2sheetid, SHEET_NAME+'\n'+pformat(title2sheetid)
    SHEET_ID = title2sheetid[SHEET_NAME]

    rows = [["dir", "file", "include"]]
    requests = [{
        "updateCells": {
            "range": {
                "sheetId": SHEET_ID,
            },
            "fields": "userEnteredFormat",
        }
    }]

    def change(old, new):
        if 'models' in new[0]:
            return old[1] == new[1]
        else:
            return old[0] == new[0]

    def k(r):
        if 'models' in r[0]:
            return ('models', r[0], r[1], r[2])
        elif 'cells' in r[0]:
            return ('cells', r[0], r[2], r[1])
        else:
            return ('', r[0], r[1], r[2])

    with open('spice-includes.csv', newline='') as f:
        for i, r in enumerate(sorted(csv.reader(f), key=k)):
            r[0] = r[0].replace(spice_dir, '')
            rows.append(r)

            if i == 0:
                continue
            if change(r, rows[-2]):
                continue

            requests.append({
              "updateBorders": {
                "range": {
                  "sheetId": SHEET_ID,
                  "startRowIndex": i,
                  "endRowIndex": i+1,
                  "startColumnIndex": 0,
                },
                "bottom": {
                  "style": "DASHED",
                  "width": 1,
                  "color": {
                    "blue": 1.0
                  },
                },
              }
            })

    assert rows, rows
    print("-"*75)
    for r in rows:
        print(r)
    print("-"*75)

    result = service.spreadsheets().values().clear(
        spreadsheetId=gsheetId,
        range=SHEET_NAME,
    ).execute()

    result = service.spreadsheets().values().update(
        spreadsheetId=gsheetId,
        valueInputOption='RAW',
        range=SHEET_NAME,
        body=dict(
            majorDimension='ROWS',
            values=rows)
    ).execute()
    print("Imported values for 'New names'")

    result = service.spreadsheets().batchUpdate(
        spreadsheetId=gsheetId,
        body={'requests':requests},
    ).execute()
    print("Updating formatting for 'New names'")


if __name__ == "__main__":
    sys.exit(main(sys.argv))
