import os
import shutil
import subprocess
import sys
from pathlib import Path

from clarabot_nano_common.utility.path.java import java_compatible_absolute_path

from dev_tools.utility.git import path_has_uncommitted_changes_by_git
from dev_tools.utility.path import ROOT

PICOTURE_ROOT = ROOT / "clarabot_nano" / "picoture"
PICOTURE_JAR = PICOTURE_ROOT / "dist" / "Picoture.jar"
PICOTURE_DEPENDENCY_LICENSE = PICOTURE_ROOT / "dist" / "dependency-license.json"


def build_picoture(force: bool = True) -> Path:
    if not PICOTURE_JAR.is_file() or force or path_has_uncommitted_changes_by_git("clarabot_nano/picoture/"):
        # clean dist (redundant as gradle build cleans it)
        picoture_dist_dir = PICOTURE_JAR.parent
        if picoture_dist_dir.exists():
            shutil.rmtree(picoture_dist_dir)
        # check Java
        java_exe = shutil.which("java.exe" if sys.platform.startswith("win") else "java")
        if not java_exe:
            raise Exception("Java 11+ is needed to compile Pictorue")
        gradlew = [
            java_compatible_absolute_path(
                PICOTURE_ROOT / ("gradlew.bat" if sys.platform.startswith("win") else "gradlew")
            )
        ]
        # We need to hack the gradle-wrapper.properties file because placing the gradle distribution zip anywhere
        # is not recognized and there is no support to dynamically point to a local file. I'm sure this is for good
        # reason as well, and I'm the odd one that does not want to wait 3 hours for a gradle download each time I
        # make a clean build. I'd also note that "just setup a local mirror/server with the gradle distribution
        # anywhere you go" or the "dude just commit the 120MB zip into your repository" recommended workarounds
        # are asinine.
        if os.environ.get("PICOTURE_GRADLE_RELEASE_PATH"):
            gradlew_props_path = PICOTURE_ROOT / "gradle/wrapper/gradle-wrapper.properties"
            prop_lines = gradlew_props_path.read_text().split("\n")
            new_line = f"distributionUrl=file\\://{os.environ['PICOTURE_GRADLE_RELEASE_PATH']}"
            for i in range(len(prop_lines)):
                if prop_lines[i].startswith("distributionUrl="):
                    prop_lines[i] = new_line
                    break
            else:
                prop_lines.insert(0, new_line)
            gradlew_props_path.write_text("\n".join(prop_lines))
        # build
        try:
            subprocess.check_output(
                [*gradlew, "buildAll"],
                stderr=subprocess.STDOUT,
                universal_newlines=True,
                # Even the cmd.exe utility has no support for UNC... who would have guessed...
                cwd=java_compatible_absolute_path(PICOTURE_ROOT),
            )
        except subprocess.CalledProcessError as e:
            print(e.stdout)
            raise e
        if not PICOTURE_JAR.is_file():
            raise Exception("Picoture.jar is not found after build.")
        if not PICOTURE_DEPENDENCY_LICENSE.is_file():
            raise Exception("Third-party licenses file for Picoture is not found after build.")
        try:
            subprocess.check_output(
                [java_exe, "-jar", java_compatible_absolute_path(PICOTURE_JAR), "--version"],
                stderr=subprocess.STDOUT,
                universal_newlines=True,
            )
        except subprocess.CalledProcessError as e:
            print(e.stdout)
            raise e
    return PICOTURE_JAR
