import shutil
from pathlib import Path

from dev_tools.build.deps.jre import build_deps_jre, get_java_version, get_java_modules
from dev_tools.build.deps.picoture import get_picoture_version
from dev_tools.build.deps.solr import cache_solr_release_package, build_deps_solr
from dev_tools.build.deps.tika import cache_tika_server, build_deps_tika


def build_deps(cache_dir: Path, deps_dir: Path, picoture_jar: Path, force: bool = False, skip_signing: bool = False):
    tika_dir_path, tika_version = cache_tika_server(cache_dir)
    solr_package_path, solr_version = cache_solr_release_package(cache_dir)
    java_version = get_java_version()
    picoture_version = get_picoture_version(picoture_jar)

    fingerprint = (
        "Clarabot Nano - dependency descriptor\n"
        f"Java:\n{java_version} - full-link\n"
        f"Solr:\n{solr_version}\n"
        f"Tika:\n{tika_version}\n"
        f"Picoture:\n{picoture_version}\n"
    )
    deps_fingerprint_path = deps_dir / ".build"
    rebuild = True
    if deps_fingerprint_path.is_file() and not force:
        cache_build_fingerprint = deps_fingerprint_path.read_text("utf-8")
        if cache_build_fingerprint == fingerprint:
            rebuild = False
    if rebuild:
        if deps_dir.exists():
            shutil.rmtree(deps_dir)
        deps_dir.mkdir(parents=True, exist_ok=True)
        # build dependencies ready for use
        tika_dir = build_deps_tika(deps_dir, tika_dir_path)
        solr_dir = build_deps_solr(deps_dir, solr_package_path)
        # build custom jre from system java
        # NOTE: Normally the jdeps and jlink tools would be used to create an optimized JRE that contains just the
        # necessary modules for our use-case. However, through much hardship, trial and error, we've come to realize
        # that the jdeps tool is not reliable. There are several issues that make its utilization hardly possible,
        # end even if we do make it produce an output, there are some dependencies that it does not pick up on.
        # Here is a quick rundown of the specific issues that prevents us from using it:
        #   1. Some JAR files do not have module descriptors and the auto-generation fails for them for reasons we
        #      do not care about... For example, jdeps fails on the xalan and batic-script dependencies with:
        #      "Unable to derive module descriptor for ..."
        #      This is in line with the jar utility where "jar -d -f xalan.jar" produces the same error as well.
        #      Since this error cannot be ignored, jdeps is unusable as long as these jars are in the module-path.
        #   2. Some JAR files export  to the same module, while that is no longer valid since some Java packaging
        #      change. The error can't be ignored and as long as two such JAR files are in the module-path, jdeps
        #      will not work like: "Error: Modules solr.solrj.zookeeper and solr.solrj export package "
        #      "org.apache.solr.common to module j2objc.annotations"
        #   3. Even if the above issues do not manifest, there are frequently missing deps that are simply "not found".
        #      Passing the new "--ignore-missing-deps" option (11.0.11+) can ignore them, but this is not reassuring.
        #   4. The 3rd issue sounds especially troublesome after the fact that even without any missing deps, jdeps has
        #      not picked up an actually used dependency at least once before. From Tika 1.26 "jdk.charsets" was not
        #      picked up by jdeps, yet it missing prevented processing some documents that would otherwise succeed.
        #   5. Weird nonexistent modules are also returned by jdeps sometimes. I'm guessing these must be some mistake
        #      or internal quackery:
        #       - "jdk8internals" but I'm on Java 11 anyways...
        #       - "kotlin.stdlib.jdk7",  jdk7, for what?
        #      If pass them to jlink, it will fail because there are no modules named as such...
        # The first two issues can hardly be solved. The mainline Java development team (and Oracle?) is of the opinion
        # that all Java modules should strictly follow the new specification, without exceptions and, no matter if
        # "they actually run", the jdeps tool does not need to process them there is no attempt to make it work and be
        # useful. The community made JARs that have these various issues do not care much about it either, because
        # "it is not breaking" (yet?) and posted issues about them are met with confusion and finger pointing usually.
        # If we were to use jdeps with an empty module-path the individual modules can be inspected by ignoring the
        # missing deps. In theory since we inspect them all, every JRE-module should be discovered that is used by
        # transitional dependencies. However, the 4th point makes me scratch my head in disbelief as to what end am I
        # even trying to make this work? I've tried the jdeps tool from Java 17 as well. It behaves exactly the same
        # as the one from Java 11.
        # The only thing that was made clear after trying as hard as possible to make an optimized JRE link: "jdeps
        # is unsuitable for what it was made for, and there is no any indication that it will get better any time"
        # So, we jlink all the available modules to make sure nothing is missing. The result JRE is bigger by
        # approximately 25MB... at this point I'll take that.
        jre_deps = set(get_java_modules())
        build_deps_jre(deps_dir, jre_deps, skip_signing=skip_signing)
        # finish
        deps_fingerprint_path.write_text(fingerprint, "utf-8")
