# Copyright 2023 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import annotations

from textwrap import dedent

import pytest

from pants.backend.python.util_rules import pex
from pants.backend.python.util_rules.lockfile_diff import _generate_python_lockfile_diff
from pants.core.goals.generate_lockfiles import GenerateLockfileResult, LockfileDiff
from pants.engine.rules import rule
from pants.testutil.rule_runner import PYTHON_BOOTSTRAP_ENV, QueryRule, RuleRunner


@rule
async def helper_fixture(result: GenerateLockfileResult) -> LockfileDiff:
    return await _generate_python_lockfile_diff(result.digest, result.resolve_name, result.path)


@pytest.fixture
def rule_runner() -> RuleRunner:
    rule_runner = RuleRunner(
        rules=[
            helper_fixture,
            *pex.rules(),
            QueryRule(LockfileDiff, [GenerateLockfileResult]),
        ]
    )
    rule_runner.set_options([], env_inherit=PYTHON_BOOTSTRAP_ENV)
    return rule_runner


def test_load_lockfile(rule_runner: RuleRunner) -> None:
    rule_runner.write_files({"reqs/test.lock": lockfile_contents["old"]})
    snapshot = rule_runner.make_snapshot({"reqs/test.lock": lockfile_contents["new"]})
    lockfile = GenerateLockfileResult(
        digest=snapshot.digest,
        resolve_name="testing",
        path="reqs/test.lock",
        diff=None,
    )
    diff = rule_runner.request(LockfileDiff, [lockfile])
    assert diff.path == "reqs/test.lock"
    assert diff.resolve_name == "testing"
    assert {req: tuple(map(str, vers)) for req, vers in diff.upgraded.items()} == dict(
        cowsay=("4.0", "5.0")
    )


lockfile_contents = dict(
    old=dedent(
        """\
        // This lockfile was autogenerated by Pants. To regenerate, run:
        //
        //    ./pants run build-support/bin/generate_builtin_lockfiles.py"
        //
        // --- BEGIN PANTS LOCKFILE METADATA: DO NOT EDIT OR REMOVE ---
        // {
        //   "version": 3,
        //   "valid_for_interpreter_constraints": [
        //     "CPython==3.9.*"
        //   ],
        //   "generated_with_requirements": [
        //     "cowsay<5"
        //   ],
        //   "manylinux": "manylinux2014",
        //   "requirement_constraints": [],
        //   "only_binary": [],
        //   "no_binary": []
        // }
        // --- END PANTS LOCKFILE METADATA ---

        {
          "allow_builds": true,
          "allow_prereleases": false,
          "allow_wheels": true,
          "build_isolation": true,
          "constraints": [],
          "locked_resolves": [
            {
              "locked_requirements": [
                {
                  "artifacts": [
                    {
                      "algorithm": "sha256",
                      "hash": "2594b11d6624fff4bf5147b6bdd510ada54a7b5b4e3f2b15ac2a6d3cf99e0bf8",
                      "url": "https://files.pythonhosted.org/packages/b7/65/38f31ef16efc312562f68732098d6f7ba3b2c108a4aaa8ac8ba673ee0871/cowsay-4.0-py2.py3-none-any.whl"
                    },
                    {
                      "algorithm": "sha256",
                      "hash": "a9e1e5f957054010b7faa6406deb5f6aa5cb674498118bbbed0151f92c2dc20e",
                      "url": "https://files.pythonhosted.org/packages/e8/15/fcfe67988ffd8e6256363174ca78fca86c927f8e6e618fd178f95a97d4d6/cowsay-4.0.tar.gz"
                    }
                  ],
                  "project_name": "cowsay",
                  "requires_dists": [],
                  "requires_python": null,
                  "version": "4.0"
                }
              ],
              "platform_tag": null
            }
          ],
          "path_mappings": {},
          "pex_version": "2.1.116",
          "pip_version": "20.3.4-patched",
          "prefer_older_binary": false,
          "requirements": [
            "cowsay<5"
          ],
          "requires_python": [
            "==3.9.*"
          ],
          "resolver_version": "pip-2020-resolver",
          "style": "universal",
          "target_systems": [
            "linux",
            "mac"
          ],
          "transitive": true,
          "use_pep517": null
        }
        """
    ),
    new=dedent(
        """\
        // This lockfile was autogenerated by Pants. To regenerate, run:
        //
        //    ./pants run build-support/bin/generate_builtin_lockfiles.py"
        //
        // --- BEGIN PANTS LOCKFILE METADATA: DO NOT EDIT OR REMOVE ---
        // {
        //   "version": 3,
        //   "valid_for_interpreter_constraints": [
        //     "CPython==3.9.*"
        //   ],
        //   "generated_with_requirements": [
        //     "cowsay"
        //   ],
        //   "manylinux": "manylinux2014",
        //   "requirement_constraints": [],
        //   "only_binary": [],
        //   "no_binary": []
        // }
        // --- END PANTS LOCKFILE METADATA ---

        {
          "allow_builds": true,
          "allow_prereleases": false,
          "allow_wheels": true,
          "build_isolation": true,
          "constraints": [],
          "locked_resolves": [
            {
              "locked_requirements": [
                {
                  "artifacts": [
                    {
                      "algorithm": "sha256",
                      "hash": "c00e02444f5bc7332826686bd44d963caabbaba9a804a63153822edce62bbbf3",
                      "url": "https://files.pythonhosted.org/packages/6b/b8/9f497fd045d74fe21d91cbe8debae0b451229989e35b539d218547d79fc6/cowsay-5.0.tar.gz"
                    }
                  ],
                  "project_name": "cowsay",
                  "requires_dists": [],
                  "requires_python": null,
                  "version": "5.0"
                }
              ],
              "platform_tag": null
            }
          ],
          "path_mappings": {},
          "pex_version": "2.1.116",
          "pip_version": "20.3.4-patched",
          "prefer_older_binary": false,
          "requirements": [
            "cowsay"
          ],
          "requires_python": [
            "==3.9.*"
          ],
          "resolver_version": "pip-2020-resolver",
          "style": "universal",
          "target_systems": [
            "linux",
            "mac"
          ],
          "transitive": true,
          "use_pep517": null
        }
        """
    ),
)
