import os
import platform
import shutil
import subprocess
import tempfile
import time
import zipfile
from pathlib import Path

from dev_tools.build.utility import get_first_file_found

HERE = os.path.abspath(os.path.dirname(__file__))


def build_installer(development: bool, frozen_dir: Path, frozen_version: str, skip_signing: bool):
    platform_tag = platform.machine().lower()
    if platform_tag != "amd64":
        raise Exception(f"unexpected platform: {platform_tag}")  # could be build on arm64 at all?
    inno_setup_compiler = get_first_file_found("iscc.exe", Path("C:/Program Files (x86)/Inno Setup 6/iscc.exe"))
    d = Path(tempfile.mkdtemp())
    try:
        iss = Path(HERE, "clarabot-nano.iss").read_text("utf-8")
        iss = iss.replace('#define ApplicationVersion "VERSION"', f'#define ApplicationVersion "{frozen_version}"')
        iss = iss.replace('#define FrozenPath "FROZEN-PATH"', f'#define FrozenPath "{frozen_dir}"')
        iss = iss.replace("OutputDir={#FrozenPath}\\..", f"OutputDir={frozen_dir.parent}")
        iss = iss.replace(
            "OutputBaseFilename=clarabot-nano", f"OutputBaseFilename=clarabot-nano-{frozen_version}-{platform_tag}"
        )
        build_iss = d / "clarabot-nano.iss"
        build_iss.write_text(iss, "utf-8")
        shutil.copy(Path(HERE, "Hungarian.isl"), d)
        i = 0
        while True:
            time.sleep(1)
            try:
                subprocess.check_call([inno_setup_compiler, str(build_iss)])
                break
            except subprocess.CalledProcessError as e:
                if i > 2:
                    raise e
                print("retrying inno setup compilation:", e)
                i += 1
        # NOTE: The singing must be done by the compiler for the uninstaller and sub-executables to be signed!
        # if not skip_signing:
        #     sign_file_for_authenticity(frozen_dir.parent / f"{frozen_dir.name}.exe")
    except Exception:
        raise
    else:
        shutil.rmtree(d)


def build_archive(development: bool, frozen_dir: Path, frozen_version: str):
    archive_root = frozen_dir.parent
    with zipfile.ZipFile(frozen_dir.parent / f"{frozen_dir.name}.zip", "w", zipfile.ZIP_DEFLATED) as zf:
        for root, _, files in os.walk(frozen_dir):
            for file in files:
                p = Path(root, file)
                zf.write(p, str(p.relative_to(archive_root)))
