#!/usr/bin/python3

import os.path
from os import makedirs
from glob import glob
import re
import itertools

NULL_TOKENS = ['nulls', 'nulls1', 'nulls2', 'nulls3']
NO_NULL_TOKENS = ['no_nulls', 'no_nulls1', 'no_nulls2', 'no_nulls3']

TOKEN_SET = NULL_TOKENS + NO_NULL_TOKENS

def extract_tokens(line):
    line = re.sub('[^a-zA-Z0-9_]', ' ', line).split(' ')
    return list(set([token for token in line if token in TOKEN_SET]))

def main(template_dir, query_dir):
    try:
        makedirs(query_dir)
    except:
        pass

    for f in glob(os.path.join(query_dir, '*')):
            os.remove(f)

    for f in glob(os.path.join(template_dir, '*.sql')):
        basename = os.path.basename(f)

        with open(f, 'r') as fptr:
            content = fptr.readlines()

        # Sort tokens longest first so string replace will replace no_nullsX before nullsX
        # (irrelevant ATM, but maybe useful later)
        tokens = sorted(extract_tokens(content[0]), key=lambda x: -len(x))
        if not tokens:
            raise ValueError('{} had no tokens'.format(content[0]))

        # For simplicity, we don't support mixing nulls and no_nulls
        if not all(len(token) == len(tokens[0]) for token in tokens):
            raise ValueError('cannot mix nulls and no_nulls: {}'.format(content[0]))


        template = content[0]
        for token in tokens:
            template = template.replace(token, token.upper())

        replacements = NULL_TOKENS
        if tokens[0].startswith('no'):
            replacements = NO_NULL_TOKENS

        for variant, choices in enumerate(itertools.combinations_with_replacement(replacements, len(tokens))):
            query = template
            for idx, token in enumerate(tokens):
                query = query.replace(token.upper(), choices[idx])
            fname = basename.replace('.sql', '-{}.sql'.format(variant))

            with open(os.path.join(query_dir, fname), 'w') as fptr:
                content[0] = query
                fptr.write(''.join(content))

if __name__ == '__main__':
    template_dir = os.path.abspath(os.path.join(__file__, '..', 'templates'))
    query_dir = os.path.abspath(os.path.join(__file__, '..', 'queries'))
    main(template_dir, query_dir)