from pathlib import Path
from CTA_Instance import CTA_Instance
import argparse
import os
import os.path


# This defines the CLI and handles user commands.

def run_cta(dpct_project_path, destination_path, report_path, is_report_only=False, should_validate=True):
    cta_instance = CTA_Instance(dpct_project_path, destination_path, report_path)

    # validate paths are valid
    if should_validate:
        validate_paths(cta_instance.dpct_version_root, cta_instance.cta_version_root)

    cta_instance.run_pre_analyzer()

    if not is_report_only:
        cta_instance.run_editor()
        cta_instance.run_post_analyzer()

    cta_instance.create_report_presentation()
    cta_instance.save_to_csvs()
    return cta_instance


def validate_paths(dpct_project_path, destination_path):
    '''
    :param dpct_project_path:
    :param destination_path:

    generates exceptions if directory of destination_path is not empty
    or if dpct_project_path directory contains no (nested) .dp.cpp or .dp.h files
    '''
    if os.path.exists(dpct_project_path) is False:
        raise Exception(str(dpct_project_path) + " does not exist.")

    filenames = []
    for root, dirs, files in os.walk(dpct_project_path):
        filenames.extend(files)
    state_cpp = False
    for filename in filenames:
        if filename.endswith('.cpp') or filename.endswith('.hpp'):
            state_cpp = True

    if not state_cpp:
        raise Exception(str(dpct_project_path) + " does not contain the cpp or hpp file.")
    elif os.path.exists(destination_path.parent) is False:
        raise Exception(destination_path.parent + " does not exist, destination dir cannot be created.")
    elif os.path.isdir(destination_path) is False:
        raise Exception(str(destination_path) + " is not a folder.")
    elif os.listdir(destination_path):
        raise Exception(str(destination_path) + " is not empty.")


if __name__ == '__main__':
    # implement of command line interface
    parser = argparse.ArgumentParser(description='Welcome to use Code Translation Assistant(CTA) for Intel oneAPI \n'
                                                 'We provide you several modes to use CTA which can help you easily '
                                                 'adapt the code generated by Intel oneAPI \n'
                                                 'To use CTA, you need to use command:')
    parser.add_argument('--mode', type=str, help="This is used to select the mode you want CTA to run on",
                        choices=['default', 'report_only'], )
    # parser.add_argument('-i', '--input', type=str, action='store', nargs=3)
    parser.add_argument('--project-path', type=str, action='store',
                        help='this is the project path you want to run CTA on ')
    parser.add_argument('--destination-path', type=str, action='store', help=' this is the path for the output files')
    parser.add_argument('--report-path', type=str, action='store', help='this is the path for report generated by CTA')
    parser.version = 'CTA 1.0.0'
    parser.add_argument('--version', action='version')
    args = parser.parse_args()

    if args.destination_path and not os.path.exists(args.destination_path):
        os.mkdir(args.destination_path)  # make directory

    if args.mode == 'default':
        run_cta(args.project_path, args.destination_path, args.report_path)

    if args.mode == 'report_only':
        run_cta(args.project_path, args.destination_path, args.report_path, is_report_only=True)
