import os
import shutil
import tarfile
import zipfile
from pathlib import Path

from dev_tools.utility.network import download_check_hash
from dev_tools.utility.path import ROOT


def cache_solr_release_package(cache_dir: Path):
    version = "9.4.0"
    solr_dir = cache_dir / "solr"
    solr_dir.mkdir(parents=True, exist_ok=True)
    # cache all packages for redundancy
    files = {
        f"solr-{version}.tgz": "7147caaec5290049b721f9a4e8b0c09b1775315fc4aa790fa7a88a783a45a618"
        "15b3532a938731fd583e91195492c4176f3c87d0438216dab26a07a4da51c1f5",
    }
    for filename, hash_digest in files.items():
        solr_pkg = solr_dir / filename
        if not solr_pkg.exists():
            download_check_hash(
                f"https://dlcdn.apache.org/solr/solr/{version}/{filename}",
                hash_digest,
                solr_pkg,
            )
    # select the package for this platform
    filename = f"solr-{version}.tgz"
    solr_pkg = solr_dir / filename
    if not solr_pkg.exists():
        raise Exception("Solr pkg missing in cache")
    return solr_pkg, f"\t{filename} - opti4"


def build_deps_solr(deps_dir: Path, solr_package_path: Path):
    solr_dir = deps_dir / "solr"
    with open(solr_package_path, "rb") as f:
        if solr_package_path.name.endswith(".zip"):
            with zipfile.ZipFile(f) as zf:
                zf.extractall(str(deps_dir))
        elif solr_package_path.name.endswith(".tgz"):
            tf = tarfile.open(mode="r:gz", fileobj=f)
            try:
                tf.extractall(str(deps_dir))
            finally:
                tf.close()
        else:
            assert False
    extracted_dir = deps_dir / solr_package_path.name.rpartition(".")[0]
    extracted_dir.resolve(strict=True)
    extracted_dir.rename(solr_dir)
    stripped_modules_dir = solr_dir / "_modules"
    # copy used jars from the modules to the install-dir/lib for simplicity
    for path, jar_prefixes in [
        ("analysis-extras/lib", ["icu4j-", "lucene-analysis-icu-", "solr-analysis-extras-"]),
    ]:
        for jar_prefix in jar_prefixes:
            names = [
                item.name
                for item in (solr_dir / "modules" / path).iterdir()
                if item.name.startswith(jar_prefix) and item.name.endswith(".jar")
            ]
            if len(names) != 1:
                raise Exception(f"Solr modules jar was not found: {jar_prefix}")
            tmp_dir = stripped_modules_dir / path
            tmp_dir.mkdir(parents=True, exist_ok=True)
            shutil.copy(solr_dir / "modules" / path / names[0], tmp_dir / names[0])
    # remove unused data and libs
    for name in ["bin", "docker", "docs", "example", "modules", "prometheus-exporter", "server/scripts", "server/solr"]:
        shutil.rmtree(solr_dir / name)
    for name in ["CHANGES.txt", "README.txt"]:
        os.unlink(solr_dir / name)
    stripped_modules_dir.rename(solr_dir / "modules")
    # NOTE: The WEB-INF lib dir is not stripped of unused jars, because there is no facility to remove the unnecessary
    # modules other than trial-and-error poking around like a madman.
    # Check the security.policy shipped with Solr has changed.
    solr_security_policy = (solr_dir / "server/etc/security.policy").read_text()
    if (ROOT / "clarabot_nano/resource/spawn/solr/security.policy").read_text() != solr_security_policy:
        (ROOT / "clarabot_nano/resource/spawn/solr/security.policy.new").write_text(solr_security_policy)
        raise Exception(f"Built solr security policy does not match the one in resources")
    return solr_dir
