#!/usr/bin/env python

import os
import sys
import argparse
from distutils.dir_util import copy_tree, remove_tree

import importlib
import eve_utils


def import_path(path):
    module_name = os.path.basename(path).replace('-', '_')
    spec = importlib.util.spec_from_loader(
        module_name,
        importlib.machinery.SourceFileLoader(module_name, path)
    )
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    sys.modules[module_name] = module
    return module


def remove_if_exists(folder):
    if os.path.exists(folder):
        remove_tree(folder)


def make_api(project_name):
    print(f'Creating {project_name} api')

    skel = os.path.join(os.path.dirname(eve_utils.__file__), 'skel/api')

    os.mkdir(project_name)  # TODO: ensure doesn't already exist, etc
    copy_tree(skel, project_name)

    # TODO: can the following remove_tree calls be obviated if skel is packaged differently?
    remove_if_exists(os.path.join(project_name, '__pycache__'))
    remove_if_exists(os.path.join(project_name, 'configuration', '__pycache__'))
    remove_if_exists(os.path.join(project_name, 'domain', '__pycache__'))
    remove_if_exists(os.path.join(project_name, 'hooks', '__pycache__'))
    remove_if_exists(os.path.join(project_name, 'log_trace', '__pycache__'))
    remove_if_exists(os.path.join(project_name, 'utils', '__pycache__'))

    for dname, dirs, files in os.walk(project_name):
        for fname in files:
            fpath = os.path.join(dname, fname)
            with open(fpath) as f:
                s = f.read()
            s = s.replace("{$project_name}", project_name)
            with open(fpath, "w") as f:
                f.write(s)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('api_name', help='The name of the API to create.')
    parser.add_argument('-d', '--with_docker', help='add Dockerfile and supporting files to deploy the API as a container', action='store_true')

    args = parser.parse_args()
    project_name = args.api_name  # TODO: validate, safe name, etc.
    make_api(project_name)
    
    if args.with_docker:
        add_docker_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'add_docker')
        ad = import_path(add_docker_path)
        ad.add_docker(project_name)

    print('Please run these two commands')
    print(f'  cd {project_name}')
    print('  pip install -r requirements.txt')

if __name__ == '__main__':
    main()
