# Copyright 2024 The Pigweed Authors
#
# Licensed 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
#
#     https://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.
"""Test API for bazel_roll."""

from PB.recipe_modules.pigweed.bazel_roll.cipd_package import BazelCipdPackage
from PB.recipe_modules.pigweed.bazel_roll.git_repository import GitRepository
from recipe_engine import recipe_test_api


TEST_WORKSPACE_FILE = """
git_repository(
    name = "other-repo"
    remote = "https://pigweed.googlesource.com/other/repo.git",
    commit = "invalid commit line won't be found",
)

git_repository(
    module_name = "pigweed",
    # ROLL: Multiple
    # ROLL: roll
    # ROLL: comment
    # ROLL: lines!
    commit = "1111111111111111111111111111111111111111",
    remote = "https://pigweed.googlesource.com/pigweed/pigweed.git",
    git_repository_attribute_test = "ignored",
    strip_prefix = "pw_toolchain_bazel",
)

git_repository(
    name = "missing final quote/comma so will miss this line
    remote = "https://pigweed.googlesource.com/third/repo.git",
    commit = "2222222222222222222222222222222222222222",
)

cipd_repository(
    name = "llvm_toolchain",
    build_file = "//pw_toolchain/build_external:llvm_clang.BUILD",
    path = "fuchsia/third_party/clang/${os}-${arch}",
    tag = "git_revision:8280651ad57cb9fb24a404cec2401040c28dec98",
)
"""

MULTIPLE_ROLL_WORKSPACE_FILE = """
git_repository(
    name = "pigweed",
    # ROLL: Comment line 1.
    commit = "1111111111111111111111111111111111111111",
    remote = "https://pigweed.googlesource.com/pigweed/pigweed.git",
)

# Filler
# lines
# to
# pad
# out
# the
# file.

git_override(
    module_name = "pw_toolchain",
    # ROLL: Comment line 2.
    commit = "1111111111111111111111111111111111111111",
    remote = "https://pigweed.googlesource.com/pigweed/pigweed",
    strip_prefix = "pw_toolchain_bazel",
)
"""

MULTIPLE_ROLL_WORKSPACE_FILE_2 = """
git_repository(
    name = "pigweed",
    # ROLL: Comment line 1.
    # ROLL: Comment line 2.
    # ROLL: Comment line 3.
    # ROLL: Comment line 4.
    # ROLL: Comment line 5.
    # ROLL: Comment line 6.
    # ROLL: Comment line 7.
    commit = "1111111111111111111111111111111111111111",
    remote = "https://pigweed.googlesource.com/pigweed/pigweed.git",
)

git_repository(
    name = "pw_toolchain",
    commit = "1111111111111111111111111111111111111111",
    remote = "https://pigweed.googlesource.com/pigweed/pigweed",
    strip_prefix = "pw_toolchain_bazel",
)
"""


class BazelRollTestApi(recipe_test_api.RecipeTestApi):
    """Test API for bazel_roll."""

    TEST_WORKSPACE_FILE = TEST_WORKSPACE_FILE
    MULTIPLE_ROLL_WORKSPACE_FILE = MULTIPLE_ROLL_WORKSPACE_FILE
    MULTIPLE_ROLL_WORKSPACE_FILE_2 = MULTIPLE_ROLL_WORKSPACE_FILE_2

    def cipd_entry(
        self,
        spec: str,
        name: str | None = None,
        ref: str = 'latest',
        tag: str = 'git_revision',
        comments: int = 2,
        **kwargs,
    ):
        if not name:  # pragma: no cover
            parts = spec.split('/')
            while '{' in parts[-1] or parts[-1].endswith(('-amd64', '-arm64')):
                parts.pop()
            name = parts[-1]

        if ':' not in tag:
            tag = f'{tag}:1.2.3'  # pragma: no cover

        result = []
        result.append('cipd_repository(')
        result.append(f'  name = "{name}",')
        result.append(f'  path = "{spec}",')
        result.append(f'  ref = "{ref}",')
        for i in range(comments):
            result.append(f'  # ROLL: Comment line {i}.')
        result.append(f'  tag = "{tag}",')
        for key, value in kwargs.items():
            if isinstance(value, str):
                value = f'"{value}"'
            assert isinstance(value, (str, int))
            result.append(f'  {key} = {value},')
        result.append(')')
        return '\n'.join(result)

    def git_entry(
        self,
        remote: str,
        revision: str = '3' * 40,
        branch: str | None = None,
        name: str | None = None,
        comments: int = 2,
        **kwargs,
    ):
        name = name or remote.split('/')[-1].removesuffix('.git')

        result = []
        result.append('git_override(')
        if branch:
            result.append(f'  branch = "{branch}",')  # pragma: no cover
        result.append(f'  name = "{name}",')
        result.append(f'  remote = "{remote}",')
        for i in range(comments):
            result.append(f'  # ROLL: Comment line {i}.')
        result.append(f'  commit = "{revision}",')
        for key, value in kwargs.items():
            if isinstance(value, str):
                value = f'"{value}"'
            assert isinstance(value, (str, int))
            result.append(f'  {key} = {value},')
        result.append(')')
        return '\n'.join(result)

    def workspace_file(
        self,
        prefix: str,
        *entries: BazelCipdPackage | GitRepository,
    ):
        if prefix:
            prefix = f'{prefix.rstrip(".")}.'
        return self.override_step_data(
            f'{prefix}read old WORKSPACE',
            self.m.file.read_text('\n\n'.join(entries)),
        )

    def cipd_package(
        self,
        *,
        name='',
        workspace_path='',
        spec='fuchsia/third_party/clang/${os}-${arch}',
        ref='latest',
        tag='git_revision',
        allow_mismatched_refs=False,
    ):
        return BazelCipdPackage(
            workspace_path=workspace_path,
            name=name,
            spec=spec,
            ref=ref,
            tag=tag,
            allow_mismatched_refs=allow_mismatched_refs,
        )

    def git_repo(
        self,
        *,
        name='',
        workspace_path='',
        remote='https://pigweed.googlesource.com/pigweed/pigweed',
        branch='main',
    ):
        return GitRepository(
            workspace_path=workspace_path,
            name=name,
            remote=remote,
            branch=branch,
        )
