#!/usr/bin/env python3

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

from IPython import embed

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 = '1oXS-a_XD7AzWOEnbJB9VvEISLW_5DydZQeVtdOuHFVE'


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)


RE_LAYERS_SPLIT = re.compile('[^a-z0-9:]+', flags=re.I)


def idx2col(i):
    assert i < 25, "FIXME: Can't handle multi-letter columns yet"
    return chr(ord('A')+i)


def cap_conv(header, r):
    METAL = header.index('metal')
    r[METAL] = [x for x in RE_LAYERS_SPLIT.split(r[METAL].lower()) if x]

    SHIELD = header.index('shield')
    if r[SHIELD] == 'None':
        r[SHIELD] = []
    else:
        r[SHIELD] = [x for x in RE_LAYERS_SPLIT.split(r[SHIELD].lower()) if x]

    FLOAT = header.index('float')
    r[FLOAT] = [x for x in RE_LAYERS_SPLIT.split(r[FLOAT].lower()) if x]
    return r


def res_conv(header, r):
    LAYERS = header.index('layers')
    r[LAYERS] = [x for x in RE_LAYERS_SPLIT.split(r[LAYERS].lower()) if x]
    return r


def download_custom(service, ctype, conversion_func):

    sheetname = 'Export to Audit - ' + ctype
    outfile = ctype.lower()[:3]+'_custom.csv'

    result = service.spreadsheets().values().get(
        spreadsheetId=gsheetId,
        range=sheetname+'!2:2',
    ).execute()
    header = result.get('values', [])[0]
    assert 'props' in header, header
    PROPS_IDX = header.index('props')
    PROPS_COL = idx2col(PROPS_IDX)

    result = service.spreadsheets().values().get(
        spreadsheetId=gsheetId,
        range=sheetname+'!A:'+PROPS_COL,
    ).execute()
    values = result.get('values', [])

    while not values[0]:
        values.pop(0)

    header = values.pop(0)
    assert 'props' == header[-1]
    assert header[0] == 'use', repr(header)
    assert header[1] == 'key', repr(header)
    keys = set()
    with open(outfile, 'w', newline='') as f:
        w = csv.writer(f)
        w.writerow(header[1:])
        for i, r in enumerate(values):
            if not r or not r[0] or r[0].strip() == '0':
                continue

            while len(r) < len(header):
                r.append('')

            assert len(header) == len(r), (
                    repr((len(header), len(r)))+'\n'+
                    repr(header)+'\n'+
                    repr(r))

            r = conversion_func(header, r)

            r.pop(0)

            assert r[0] not in keys, (
                    r[0]+'\n'+
                    pformat(r)+'\n'+
                    pformat(keys))
            keys.add(r[0])

            w.writerow(r)

    with open(outfile) as f:
        print()
        print(outfile, "info")
        print('-'*75)
        print(f.read())
        print('-'*75)




def main(argv):

    service = get_service()

    download_custom(
        service,
        'BJT',
        lambda h, r: r,
    )
    download_custom(
        service,
        'Capacitors',
        cap_conv,
    )
    download_custom(
        service,
        'Diodes',
        lambda h, r: r,
    )
    download_custom(
        service,
        'Resistors',
        res_conv,
    )
    download_custom(
        service,
        'Vias',
        res_conv,
    )
    download_custom(
        service,
        'Special',
        lambda h, r: r,
    )


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