#!/bin/env python3

import zipfile
import sys
import shutil
import tempfile
import subprocess
import os
import pathlib
import datetime

template_directory = pathlib.Path("PackageTemplates/")
macos_template = template_directory / "isometric-park-template.app"
windows_template = template_directory / "isometric-park-windows-template"
linux_template = template_directory / "isometric-park-linux-template"

sourcedir = "isometric-park-fna/bin/Release"
destination_directory = pathlib.Path("isometric-park-fna/bin/")


start_date = datetime.datetime(2019, 1, 1)


def months_betweeen(start, end):
    return ((end.year - start.year) * 12) + (end.month - start.month)


def create_version_string():
    today = datetime.datetime.today()
    months = months_betweeen(start_date, today) + 1

    version_string = f"0.{months}.{today.strftime('%d')}"

    print(f"Version string: {version_string}")


def make_linux(suffix="new"):
    new_name = destination_directory / (linux_template.name[:-9] + "-" + suffix)
    # shutil.rmtree(new_name)
    shutil.copytree(linux_template, new_name)

    for (dirpath, _dirname, files) in os.walk(sourcedir):
        for file in files:
            source = pathlib.Path(dirpath) / file
            destination = pathlib.Path(new_name) / os.path.relpath(dirpath, sourcedir) / pathlib.Path(file)

            print(source, destination)

            os.makedirs(destination.parent, exist_ok=True)
            if destination.parent.is_dir() and not destination.parent.exists():
                os.mkdir(destination.parent)
            elif source.is_dir() and not destination.exists():
                print("Copying whole directory!")
                shutil.copytree(source, destination)
            else:
                shutil.copy2(source, destination)

    print(pathlib.Path(new_name) / "isometric-park-fna.exe",
                pathlib.Path(new_name) / "isometric-park.exe")
    shutil.move(pathlib.Path(new_name) / "isometric-park-fna.exe",
                pathlib.Path(new_name) / "isometric-park.exe")

    new_zip_name = new_name.parent / (new_name.name + ".zip")

    with zipfile.ZipFile(new_zip_name, "w",
                         #May be able to use something better on Linux:
                         compression=zipfile.ZIP_DEFLATED) as f:
        for (dirpath, _dirname, files) in os.walk(new_name):
            for file in files:
                source = pathlib.Path(dirpath) / file
                f.write(source, pathlib.Path(os.path.relpath(sourcedir, dirpath)) / os.path.relpath(dirpath, sourcedir) / pathlib.Path(file))
                # f.write(source, pathlib.Path(os.path.relpath(sourcedir, dirpath)) / os.path.relpath(dirpath, sourcedir) / pathlib.Path(file))


def make_windows(suffix="new"):
    new_name = destination_directory / (windows_template.name[:-9] + "-" + suffix)
    # shutil.rmtree(new_name)
    shutil.copytree(windows_template, new_name)

    for (dirpath, _dirname, files) in os.walk(sourcedir):
        for file in files:
            source = pathlib.Path(dirpath) / file
            destination = pathlib.Path(new_name) / os.path.relpath(dirpath, sourcedir) / pathlib.Path(file)

            print(source, destination)

            os.makedirs(destination.parent, exist_ok=True)
            if source.parent.is_dir() and not destination.parent.exists():
                # shutil.copytree(source.parent, destination.parent)
                os.mkdir(destination.parent)
            elif source.is_dir() and not destination.exists():
                shutil.copytree(source, destination)
            else:
                shutil.copy2(source, destination)

    shutil.move(pathlib.Path(new_name) / "isometric-park-fna.exe",
                pathlib.Path(new_name) / "isometric-park.exe")

    new_zip_name = new_name.parent / (new_name.name + ".zip")

    with zipfile.ZipFile(new_zip_name, "w",
                         #Windows doesn't natively support other formats
                         #(besides uncompressed) in my testing:
                         compression=zipfile.ZIP_DEFLATED) as f:
        for (dirpath, _dirname, files) in os.walk(new_name):
            for file in files:
                source = pathlib.Path(dirpath) / file
                f.write(source, pathlib.Path(os.path.relpath(sourcedir, dirpath)) / os.path.relpath(dirpath, sourcedir) / pathlib.Path(file))


def make_macos(suffix="new"):

    new_name = destination_directory / (macos_template.name[:-13] + "-" + suffix + ".app" + "/")

    # shutil.rmtree(new_name)
    shutil.copytree(macos_template, new_name)

    for (dirpath, _dirname, files) in os.walk(sourcedir):
        for file in files:
            source = pathlib.Path(dirpath) / file
            destination = new_name / "Contents" / "Resources" / os.path.relpath(dirpath, sourcedir) / file

            print(source, destination)

            if source.parent.is_dir() and not destination.parent.exists():
                # shutil.copytree(source.parent, destination.parent)
                os.mkdir(destination.parent)
            elif source.is_dir() and not destination.exists():
                shutil.copytree(source, destination)
            else:
                shutil.copy2(source, destination)

    shutil.move(pathlib.Path(new_name) / "Contents" / "Resources" / "isometric-park-fna.exe",
                pathlib.Path(new_name) / "Contents" / "Resources" / "isometric-park.exe")


def make_source(suffix="new"):

    new_name = destination_directory / ("isometric-park-source" + "-" + suffix
                                        + ".zip")

    with tempfile.TemporaryDirectory() as temp:
        print(subprocess.getoutput(f"hg clone . {temp}"))

        with zipfile.ZipFile(new_name, "w",
                             #Windows doesn't natively support other formats
                             #(besides uncompressed) in my testing:
                             compression=zipfile.ZIP_DEFLATED) as f:
            for (dirpath, _dirname, files) in os.walk(temp):
                for file in files:
                    source = pathlib.Path(dirpath) / file
                    print(os.path.relpath(source, temp))
                    f.write(source, os.path.relpath(source, temp))


def main():
    if len(sys.argv) > 1:
        command = sys.argv[1]

        if command.lower() == "macos":
            if len(sys.argv) > 2:
                make_macos(sys.argv[2])
            else:
                make_macos()
        elif command.lower() in ("win", "windows"):
            if len(sys.argv) > 2:
                make_windows(sys.argv[2])
            else:
                make_windows()
        elif command.lower() == "linux":
            if len(sys.argv) > 2:
                make_linux(sys.argv[2])
            else:
                make_linux()
        elif command.lower() == "source":
            if len(sys.argv) > 2:
                make_source(sys.argv[2])
            else:
                make_source()
        elif command.lower() == "version":
            create_version_string()
    else:
        pass


if __name__ == '__main__':
    main()
