# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

"""Exercise actual distributions without importing runtime/native dependencies.

Run with ``python dev/test_packaging.py`` after installing the build tools.
The same suite runs on Python 3.6 and modern Python in CI.
"""
import email
import os
from pathlib import Path
import runpy
import shutil
import subprocess
import sys
import tarfile
import tempfile
import unittest
import zipfile

from packaging.markers import default_environment
from packaging.requirements import Requirement
from packaging.utils import canonicalize_name
from packaging.version import Version

try:
    import tomllib
except ImportError:
    import tomli as tomllib


def command(args, cwd, env=None):
    result = subprocess.run(args, cwd=str(cwd), env=env,
                            stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    if result.returncode:
        raise AssertionError(result.stdout.decode("utf-8", errors="replace")[-8000:])
    return result.stdout.decode("utf-8")


def wheel_contents(path):
    with zipfile.ZipFile(str(path)) as archive:
        names = archive.namelist()
        metadata = email.message_from_bytes(archive.read(next(
            name for name in names if name.endswith(".dist-info/METADATA"))))
        full_version = archive.read("pypaimon/_full_version").decode().strip()
    return names, metadata, full_version


class PackagingTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.temp = tempfile.TemporaryDirectory(prefix="pypaimon-packaging-")
        cls.root = Path(cls.temp.name)
        cls.source = cls.root / "source"
        project = Path(__file__).resolve().parent.parent
        shutil.copytree(str(project), str(cls.source), ignore=shutil.ignore_patterns(
            "build", "dist", "*.egg-info", "__pycache__", ".pytest_cache", ".venv"))
        cls.env = os.environ.copy()
        for key in ("GIT_DIR", "GIT_WORK_TREE", "PYPAIMON_BUILD_VERSION"):
            cls.env.pop(key, None)
        cls.env.update(GIT_AUTHOR_DATE="2020-01-02T03:04:05+00:00",
                       GIT_COMMITTER_DATE="2020-01-02T03:04:05+00:00")
        cls.commit = cls.init_git(cls.source)
        base = runpy.run_path(str(cls.source / "pypaimon/_version.py"))["VERSION"]
        cls.version = str(Version(base + "20200102" if base.endswith(".dev") else base))
        with (cls.source / "pyproject.toml").open("rb") as config:
            cls.config = tomllib.load(config)
        cls.dist = cls.root / "custom-output"
        cls.build(cls.source, cls.dist)
        cls.wheel = next(cls.dist.glob("*.whl"))
        cls.sdist = next(cls.dist.glob("*.tar.gz"))

    @classmethod
    def tearDownClass(cls):
        cls.temp.cleanup()

    @classmethod
    def init_git(cls, root):
        for args in (["init", "-q"], ["config", "user.name", "Packaging Test"],
                     ["config", "user.email", "test@example.com"], ["add", "."],
                     ["commit", "-qm", "test source"]):
            command(["git"] + args, root, cls.env)
        return command(["git", "rev-parse", "HEAD"], root, cls.env).strip()

    @classmethod
    def build(cls, source, output, extra=(), env=None):
        command([sys.executable, "-m", "build", "--no-isolation", "--outdir",
                 str(output)] + list(extra), source, env or cls.env)

    def test_sdist_and_wheel_share_version_and_commit(self):
        self.assertEqual(2, len(list(self.dist.iterdir())))
        self.assertEqual("pypaimon-{}.tar.gz".format(self.version), self.sdist.name)
        self.assertEqual("pypaimon-{}-py3-none-any.whl".format(self.version), self.wheel.name)
        _, metadata, full_version = wheel_contents(self.wheel)
        self.assertEqual(self.version, metadata["Version"])
        self.assertEqual("python-{}-{}".format(self.version, self.commit), full_version)
        with tarfile.open(str(self.sdist)) as archive:
            prefix = "pypaimon-{}/".format(self.version)
            self.assertEqual(full_version, archive.extractfile(
                prefix + "pypaimon/_full_version").read().decode().strip())

    def test_distribution_contents(self):
        names, metadata, _ = wheel_contents(self.wheel)
        self.assertEqual(">=3.6", metadata["Requires-Python"])
        self.assertFalse(any(name.startswith("pypaimon/tests/")
                             for name in names))
        self.assertFalse(any(name.endswith((".so", ".pyd", ".jar")) for name in names))
        self.assertIn("pypaimon/_version.py", names)
        execution_files = (
            "pypaimon/table/source/search_execution.py",
            "pypaimon/ray/search_execution.py",
            "pypaimon/execution/native/read/search_execution.py",
            "pypaimon/execution/python/read/search/distributed_search.py",
            "pypaimon/execution/python/read/search/distributed_vector_search.py",
            "pypaimon/execution/python/read/search/distributed_full_text_search.py",
            "pypaimon/execution/python/map_blob_key_serializer.py",
            "pypaimon/execution/python/write/external_path_provider.py",
            "pypaimon/execution/python/read/predicate_json_parser.py",
            "pypaimon/execution/python/read/blob_view_lookup.py",
            "pypaimon/execution/python/read/interval_partition.py",
            "pypaimon/execution/python/read/map_shared_shredding.py",
            "pypaimon/execution/python/read/variant_shredding.py",
            "pypaimon/execution/python/write/dynamic_bucket.py",
            "pypaimon/execution/python/write/merge_condition.py",
            "pypaimon/execution/python/write/merge_transform.py",
            "pypaimon/schema/data_type_casts.py",
            "pypaimon/utils/numeric_utils.py",
            "pypaimon/utils/temporal_utils.py",
            "pypaimon/utils/temporal_string.py",
            "pypaimon/utils/row_to_string.py",
            "pypaimon/execution/python/casting/__init__.py",
            "pypaimon/execution/python/casting/data_type_casts.py",
            "pypaimon/execution/python/casting/schema_evolution.py",
            "pypaimon/execution/python/casting/decimal_cast.py",
            "pypaimon/execution/python/casting/temporal_cast.py",
            "pypaimon/execution/python/casting/temporal_string.py",
            "pypaimon/execution/python/write/partition_spec.py",
            "pypaimon/execution/python/deletionvectors/__init__.py",
            "pypaimon/execution/python/deletionvectors/deletion_vector.py",
            "pypaimon/execution/python/deletionvectors/bitmap_deletion_vector.py",
            "pypaimon/execution/python/deletionvectors/apply_deletion_vector_reader.py",
            "pypaimon/write/backend_dispatch.py",
            "pypaimon/read/read_dispatch.py",
            "pypaimon/read/read_support.py",
            "pypaimon/read/read_explain.py",
            "pypaimon/globalindex/index_dispatch.py",
            "pypaimon/table/source/search_dispatch.py",
            "pypaimon/write/update_dispatch.py",
            "pypaimon/write/write_dispatch.py",
            "pypaimon/globalindex/vindex_input.py",
            "pypaimon/write/input_adapter.py",
            "pypaimon/write/merge_condition.py",
            "pypaimon/write/merge_transform.py",
            "pypaimon/read/datasource/torch_dataset.py",
            "pypaimon/read/datasource/ray_datasource.py",
            "pypaimon/read/datasource/split_provider.py",
            "pypaimon/write/ray_datasink.py",
            "pypaimon/execution/python/read/table_read.py",
            "pypaimon/execution/python/read/table_scan.py",
            "pypaimon/execution/python/read/auth_support.py",
            "pypaimon/execution/python/read/scan_distribution.py",
            "pypaimon/execution/python/read/format_table_read.py",
            "pypaimon/execution/python/read/format_table_scan.py",
            "pypaimon/execution/python/read/object_table_read.py",
            "pypaimon/execution/python/read/object_table_scan.py",
            "pypaimon/table/system/system_table_read.py",
            "pypaimon/table/system/system_table_scan.py",
            "pypaimon/execution/python/merge_engine_dispatch.py",
            "pypaimon/execution/python/read/search/vector_search_read.py",
            "pypaimon/execution/python/read/search/factories.py",
            "pypaimon/execution/python/read/search/hybrid_search.py",
            "pypaimon/ray/vector_index_build.py",
            "pypaimon/execution/python/globalindex/btree/btree_index_reader.py",
            "pypaimon/execution/python/globalindex/btree/block_handle.py",
            "pypaimon/execution/python/globalindex/block_compression.py",
            "pypaimon/execution/python/globalindex/key_serializer.py",
            "pypaimon/execution/python/index/pk/primary_key_index_source_policy.py",
            "pypaimon/execution/python/index/pksorted/pk_sorted_bucket_index_state.py",
            "pypaimon/execution/python/index/pksorted/pk_sorted_index_group.py",
            "pypaimon/execution/python/globalindex/vindex/vindex_vector_global_index_reader.py",
            "pypaimon/execution/python/write/table_write.py",
            "pypaimon/execution/python/write/table_commit.py",
            "pypaimon/execution/python/write/format_table_write.py",
            "pypaimon/execution/python/write/format_table_commit.py",
            "pypaimon/execution/python/write/bucket_metadata.py",
            "pypaimon/execution/native/read/table_read.py",
            "pypaimon/execution/native/read/plan.py",
            "pypaimon/execution/native/read/system_table.py",
            "pypaimon/execution/native/read/vindex_reader.py",
            "pypaimon/execution/native/write/native_write.py",
            "pypaimon/execution/native/write/native_commit.py",
            "pypaimon/execution/native/write/bucket_metadata.py",
            "pypaimon/execution/native/write/postpone_bucket.py",
            "pypaimon/read/blob_read_support.py",
            "pypaimon/read/scan_request.py",
            "pypaimon/table/source/search_types.py",
            "pypaimon/globalindex/vindex_reader.py",
            "pypaimon/write/bucket_planning.py",
            "pypaimon/write/commit_options.py",
            "pypaimon/write/input_routing.py",
        )
        for name in execution_files:
            self.assertIn(name, names)
        for name in names:
            if name.startswith("pypaimon/execution/") and name.endswith(".py"):
                self.assertIn(name.split("/")[2], ("python", "native", "__init__.py"))
        internal_aliases = (
            "pypaimon/common/external_path_provider.py",
            "pypaimon/common/map_blob_key_serializer.py",
            "pypaimon/utils/blob_view_lookup.py",
            "pypaimon/read/interval_partition.py",
            "pypaimon/casting/__init__.py",
            "pypaimon/casting/data_type_casts.py",
            "pypaimon/casting/schema_evolution.py",
            "pypaimon/casting/decimal_cast.py",
            "pypaimon/casting/temporal_cast.py",
            "pypaimon/casting/temporal_string.py",
            "pypaimon/casting/numeric_utils.py",
            "pypaimon/casting/temporal_utils.py",
            "pypaimon/casting/row_to_string.py",
            "pypaimon/write/partition_spec.py",
            "pypaimon/deletionvectors/__init__.py",
            "pypaimon/deletionvectors/deletion_vector.py",
            "pypaimon/deletionvectors/bitmap_deletion_vector.py",
            "pypaimon/deletionvectors/apply_deletion_vector_reader.py",
            "pypaimon/execution/python/globalindex/ray_build.py",
            "pypaimon/execution/python/read/system_table_read.py",
            "pypaimon/execution/python/read/system_table_scan.py",
            "pypaimon/common/merge_engine_dispatch.py",
            "pypaimon/read/native_plan.py",
            "pypaimon/read/native_row_iterator.py",
            "pypaimon/table/source/full_text_read.py",
            "pypaimon/table/source/vector_search_scan.py",
            "pypaimon/table/source/native_search_plan.py",
            "pypaimon/table/system/native_system_table.py",
            "pypaimon/globalindex/bitmap/__init__.py",
            "pypaimon/globalindex/btree/__init__.py",
            "pypaimon/globalindex/full_text/__init__.py",
            "pypaimon/globalindex/lumina/__init__.py",
            "pypaimon/globalindex/vindex/__init__.py",
            "pypaimon/globalindex/btree/block_reader.py",
            "pypaimon/globalindex/btree_format/block_handle.py",
            "pypaimon/globalindex/bitmap/bitmap_index_writer.py",
            "pypaimon/globalindex/block_compression.py",
            "pypaimon/index/pk/primary_key_index_source_policy.py",
            "pypaimon/index/pksorted/pk_sorted_bucket_index_state.py",
            "pypaimon/index/pksorted/pk_sorted_index_group.py",
        )
        for name in internal_aliases:
            self.assertNotIn(name, names)
        for suffix in ("/LICENSE", "/NOTICE"):
            self.assertTrue(any(".dist-info/" in name and name.endswith(suffix)
                                for name in names))
        with tarfile.open(str(self.sdist)) as archive:
            names = archive.getnames()
            prefix = "pypaimon-{}/".format(self.version)
            for name in ("pyproject.toml", "setup.py", "LICENSE", "NOTICE", "README.md"):
                self.assertIn(prefix + name, names)
            for name in execution_files:
                self.assertIn(prefix + name, names)
            for name in internal_aliases:
                self.assertNotIn(prefix + name, names)
            self.assertFalse(any("requirements.txt" in name or "requirements-dev.txt" in name
                                 or name.startswith(prefix + "pypaimon/tests/")
                                 for name in names))

    @staticmethod
    def active_requirements(values, environment):
        result = set()
        for value in values:
            requirement = Requirement(value)
            if requirement.marker is None or requirement.marker.evaluate(environment):
                result.add((canonicalize_name(requirement.name), str(requirement.specifier)))
        return result

    def test_metadata_preserves_core_and_extra_conditions(self):
        _, metadata, _ = wheel_contents(self.wheel)
        project = self.config["project"]
        self.assertEqual(set(project["optional-dependencies"]),
                         set(metadata.get_all("Provides-Extra")))
        for python_version in ("3.6", "3.7", "3.8", "3.11", "3.13"):
            for system in ("Linux", "Windows"):
                for extra in [""] + list(project["optional-dependencies"]):
                    with self.subTest(python=python_version, system=system, extra=extra):
                        environment = default_environment()
                        environment.update(python_version=python_version,
                                           python_full_version=python_version + ".0",
                                           platform_system=system, extra=extra)
                        expected = project["dependencies"] + project[
                            "optional-dependencies"].get(extra, [])
                        self.assertEqual(self.active_requirements(expected, environment),
                                         self.active_requirements(
                                             metadata.get_all("Requires-Dist"), environment))

    def test_readerwriterlock_python_compatibility(self):
        _, metadata, _ = wheel_contents(self.wheel)
        requirements = [Requirement(value) for value in metadata.get_all("Requires-Dist")]
        locks = [requirement for requirement in requirements
                 if canonicalize_name(requirement.name) == "readerwriterlock"]
        for python_version, supports_1_0_10 in (("3.6", False), ("3.7", False), ("3.8", True), ("3.13", True)):
            with self.subTest(python=python_version):
                environment = default_environment()
                environment.update(python_version=python_version,
                                   python_full_version=python_version + ".0", extra="")
                active = [requirement for requirement in locks
                          if requirement.marker is None or requirement.marker.evaluate(environment)]
                self.assertEqual(1, len(active))
                self.assertIn("1.0.9", active[0].specifier)
                self.assertEqual(supports_1_0_10, "1.0.10" in active[0].specifier)
                self.assertNotIn("2.0", active[0].specifier)

    def test_python_ci_dependencies_do_not_pull_native_sql(self):
        resolve = runpy.run_path(str(self.source / "dev/install.py"))["resolve_group"]
        extras = self.config["project"]["optional-dependencies"]

        def dependencies(group):
            pending = list(resolve(self.config["dependency-groups"], group))
            names, expanded = set(), set()
            while pending:
                requirement = Requirement(pending.pop())
                names.add(canonicalize_name(requirement.name))
                if canonicalize_name(requirement.name) == "pypaimon":
                    for extra in requirement.extras - expanded:
                        pending.extend(extras[extra])
                        expanded.add(extra)
            return names

        # Follow local extras too: the Rust extension previously entered the
        # ordinary Python and Torch environments indirectly through [sql].
        for group in ("torch", "python-tests", "legacy"):
            with self.subTest(group=group):
                self.assertNotIn("pypaimon-rust", dependencies(group))
        self.assertIn("pypaimon-rust", dependencies("dev"))

    def test_dev_group_reuses_product_extras(self):
        resolve = runpy.run_path(str(self.source / "dev/install.py"))["resolve_group"]
        requirements = [Requirement(value) for value in resolve(
            self.config["dependency-groups"], "dev")]
        extras = set().union(*(requirement.extras for requirement in requirements
                               if requirement.name == "pypaimon"))
        self.assertTrue({"ray", "sql", "vindex", "full-text"}.issubset(extras))
        # Product constraints belong to extras, not a second developer copy.
        names = {requirement.name for requirement in requirements}
        self.assertFalse(names.intersection({"datafusion", "paimon-vindex", "requests", "h5py"}))

    def test_sdist_rebuild_preserves_provenance_in_another_git_repo(self):
        outer = self.root / "downstream"
        outer.mkdir()
        (outer / "README").write_text("Unrelated downstream repository")
        downstream_commit = self.init_git(outer)
        self.assertNotEqual(self.commit, downstream_commit)
        with tarfile.open(str(self.sdist)) as archive:
            # This archive was just built from our test source.
            archive.extractall(str(outer))
        output = self.root / "rebuilt"
        self.build(outer / "pypaimon-{}".format(self.version), output, extra=("--wheel",))
        _, metadata, full_version = wheel_contents(next(output.glob("*.whl")))
        self.assertEqual(self.version, metadata["Version"])
        self.assertEqual("python-{}-{}".format(self.version, self.commit), full_version)

    def test_release_override_applies_to_both_formats(self):
        env = dict(self.env, PYPAIMON_BUILD_VERSION="2.2rc1")
        output = self.root / "release-candidate"
        self.build(self.source, output, env=env)
        self.assertEqual({"pypaimon-2.2rc1.tar.gz", "pypaimon-2.2rc1-py3-none-any.whl"},
                         {path.name for path in output.iterdir()})
        _, metadata, full_version = wheel_contents(next(output.glob("*.whl")))
        self.assertEqual("2.2rc1", metadata["Version"])
        self.assertEqual("python-2.2rc1-{}".format(self.commit), full_version)
        self.assertEqual("", command(["git", "diff", "--", "pypaimon/_version.py"],
                                     self.source, self.env))

    def test_invalid_release_override_fails(self):
        env = dict(self.env, PYPAIMON_BUILD_VERSION="not a version")
        result = subprocess.run([sys.executable, "-m", "build", "--no-isolation", "--sdist"],
                                cwd=str(self.source), env=env,
                                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        self.assertNotEqual(0, result.returncode)


if __name__ == "__main__":
    unittest.main(verbosity=2)
