# Copyright 2023 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 module."""

import re

from PB.recipe_modules.pigweed.bazel.options import BazelInvocation, Options
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(
    name = "pigweed",
    # ROLL: Multiple
    # ROLL: roll
    # ROLL: comment
    # ROLL: lines!
    commit = "1111111111111111111111111111111111111111",
    remote = "https://pigweed.googlesource.com/pigweed/pigweed.git",
)

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

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_repository(
    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 BazelTestApi(recipe_test_api.RecipeTestApi):
    """Test API for Bazel."""

    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 options(
        self,
        *,
        bazelisk_version='',
        cipd_json_path='',
        invocations=(('build', '//...'), ('test', '//...')),
        program=(),
    ):
        opts = Options()
        opts.cipd_json_path = cipd_json_path
        opts.bazelisk_version = bazelisk_version
        for invocation in invocations:
            invocation_proto = BazelInvocation(args=invocation)
            opts.invocations.append(invocation_proto)
        opts.program.extend([program] if isinstance(program, str) else program)
        return opts

    def properties(self, *, name='bazel_options', **kwargs):
        return self.m.properties(**{name: self.options(**kwargs)})

    def config(
        self,
        *,
        name: str = 'pigweed.json',
        programs: dict[str, list[list[str]]] = None,
        remote_cache: bool = True,
        upload_local_results: bool = True,
    ):
        if programs is None:
            programs = {
                'default': [
                    ['build', '//...'],
                    ['test', '//...'],
                ],
            }

        return self.step_data(
            f'read {name}',
            self.m.file.read_json(
                {
                    'pw': {
                        'bazel_presubmit': {
                            'remote_cache': remote_cache,
                            'upload_local_results': upload_local_results,
                            'programs': programs,
                        },
                    },
                },
            ),
        )
