import argparse
import shutil
import sys
from pathlib import Path
from textwrap import dedent
import string


class CustomTemplate(string.Template):
    delimiter = '@'  # 使用自定义的占位符，例如@{}


def generateTemplateFile(source, dist, _mapping):
    source_path = Path(source).absolute()
    dist_path = Path(dist).absolute()
    with open(source_path, 'r', encoding='utf-8') as _file:
        content = _file.read()

    template = CustomTemplate(content)
    rendered_content = template.substitute(_mapping)

    dist_path.parent.mkdir(parents=True, exist_ok=True)
    with open(dist_path, 'w', encoding='utf-8') as _file:
        _file.write(rendered_content)


TOOL_DESCRIPTION = dedent("""
    create-fluent-app: A tool to bootstrap and manage Fluent UI applications.

    This script provides an easy way to set up a new Fluent UI application with
    predefined configurations and templates. It helps streamline the process of
    creating and managing Fluent UI projects by automating repetitive tasks and
    ensuring consistency across projects.

    Usage examples:
    1. To create a new Fluent UI project:
       python create-fluent-app.py --name MyApp
    2. To specify an output directory:
       python create-fluent-app.py --out /path/to/output/dir
""")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description=TOOL_DESCRIPTION)
    parser.add_argument("-n", "--name", required=True,
                        help="Specify the name of the Fluent UI application to be created.")
    parser.add_argument("-o", "--out", required=True,
                        help="Specify the output directory where the project will be created.")
    args = parser.parse_args()
    app_name = args.name
    output_dir = Path(args.out)
    project_dir = output_dir / app_name
    project_sub_dir = output_dir / app_name / app_name
    project_cmake_dir = project_sub_dir / '.cmake'
    project_favicon_dir = project_sub_dir / 'favicon'
    if not output_dir.is_dir():
        print(f"Error: The specified output directory '{output_dir}' is not a valid directory.")
        sys.exit(1)
    if project_dir.exists():
        print(f"Error: The project '{app_name}' already exists in the directory '{output_dir}'.")
        sys.exit(1)
    try:
        project_dir.mkdir(parents=True, exist_ok=False)
        project_cmake_dir.mkdir(parents=True, exist_ok=False)
        project_favicon_dir.mkdir(parents=True, exist_ok=False)
    except Exception as e:
        print(f"Error: Failed to create the project directory '{project_dir}'. {e}")
    try:
        shutil.copytree(Path('FluentUI'), project_dir / 'FluentUI')
    except Exception as e:
        print(f"Error: Failed to copy FluentUI files to the project directory. {e}")
        sys.exit(1)
    try:
        shutil.copytree(Path('Gallery/runtime'), project_sub_dir / 'runtime')
    except Exception as e:
        print(f"Error: Failed to copy runtime files to the project directory. {e}")
        sys.exit(1)
    shutil.copytree(Path('designer'), project_dir / 'designer')
    
    shutil.copy(Path('.gitignore'), project_dir)
    shutil.copy(Path('.clang-format'), project_dir)
    
    shutil.copy(Path('Gallery/favicon/favicon.ico'), project_favicon_dir)
    shutil.copy(Path('Gallery/favicon/favicon.png'), project_favicon_dir)
    shutil.copy(Path('Gallery/favicon/favicon.icns'), project_favicon_dir)

    shutil.copy(Path('.template/logo.png'), project_sub_dir)
    shutil.copy(Path('.template/en_US.ts'), project_sub_dir / (app_name + '_en_US.ts'))
    shutil.copy(Path('.template/zh_CN.ts'), project_sub_dir / (app_name + '_zh_CN.ts'))
    shutil.copy(Path('.template/en_US.qm'), project_sub_dir / (app_name + '_en_US.qm'))
    shutil.copy(Path('.template/zh_CN.qm'), project_sub_dir / (app_name + '_zh_CN.qm'))
    shutil.copy(Path('Gallery/.cmake/InstallerScript.iss.in'), project_cmake_dir / 'InstallerScript.iss.in')
    shutil.copy(Path('Gallery/.cmake/MacOSXBundleInfo.plist.in'), project_cmake_dir / 'MacOSXBundleInfo.plist.in')
    shutil.copy(Path('Gallery/.cmake/win_app.rc.in'), project_cmake_dir / 'win_app.rc.in')
    
    shutil.copy(Path('Gallery/.cmake/linux.desktop.in'), project_cmake_dir / 'linux.desktop.in')
    shutil.copy(Path('Gallery/.cmake/linux_control.in'), project_cmake_dir / 'linux_control.in')
    shutil.copy(Path('Gallery/.cmake/linux_postinst.in'), project_cmake_dir / 'linux_postinst.in')
    shutil.copy(Path('Gallery/.cmake/linux_postrm.in'), project_cmake_dir / 'linux_postrm.in')

    mapping = dict(application_name=app_name)
    generateTemplateFile(Path('.template/RootCMakeLists.txt.in'), project_dir / 'CMakeLists.txt', mapping)
    generateTemplateFile(Path('.template/stdafx.h.in'), project_sub_dir / 'stdafx.h', mapping)
    generateTemplateFile(Path('.template/App.qml.in'), project_sub_dir / 'App.qml', mapping)
    generateTemplateFile(Path('.template/MainScreen.qml.in'), project_sub_dir / 'MainScreen.qml', mapping)
    generateTemplateFile(Path('.template/MainWindow.qml.in'), project_sub_dir / 'MainWindow.qml', mapping)
    generateTemplateFile(Path('.template/AppInfo.cpp.in'), project_sub_dir / 'AppInfo.cpp', mapping)
    generateTemplateFile(Path('.template/AppInfo.h.in'), project_sub_dir / 'AppInfo.h', mapping)
    generateTemplateFile(Path('.template/CMakeLists.txt.in'), project_sub_dir / 'CMakeLists.txt', mapping)
    generateTemplateFile(Path('.template/Log.h.in'), project_sub_dir / 'Log.h', mapping)
    generateTemplateFile(Path('.template/Log.cpp.in'), project_sub_dir / 'Log.cpp', mapping)
    generateTemplateFile(Path('.template/main.cpp.in'), project_sub_dir / 'main.cpp', mapping)

    print(f"Creating project '{app_name}' in '{output_dir}'.")
