# Copyright 2021 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.
"""Update the tokenizer database.

Note: this is not what most developers think of when they see "tokenizer". For
details see https://pigweed.dev/pw_tokenizer/.

On its face builders using this recipe could create infinite loops but they
won't because the changes created by this recipe won't cause changes in the
generated database.
"""

import re

import attr
from PB.recipes.pigweed.tokendb_updater import InputProperties

DEPS = [
    'fuchsia/auto_roller',
    'fuchsia/git',
    'fuchsia/status_check',
    'pigweed/build',
    'pigweed/checkout',
    'pigweed/environment',
    'pigweed/roll_util',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
]

PROPERTIES = InputProperties

PYTHON_VERSION_COMPATIBILITY = "PY3"


def RunSteps(api, props):  # pylint: disable=invalid-name
    api.checkout()

    tokendb_branch = props.tokendb_branch or "main"
    generated_tokendb_path = api.checkout.root.join(
        *re.split(r'/+', props.generated_tokendb_path)
    )

    if props.tokendb_host and props.tokendb_project:
        directory = (
            api.path.abs_to_path(
                api.path.split(api.path.abspath(generated_tokendb_path))[0]
            )
            or api.checkout.root
        )
        with api.step.nest('update token db repo'), api.context(cwd=directory):
            api.git.fetch('origin', tokendb_branch)
            api.git('checkout FETCH_HEAD', 'checkout', 'FETCH_HEAD')

    if bool(props.tokendb_host) != bool(props.tokendb_project):
        raise ValueError(  # pragma: no cover
            'tokendb_host ({}) and tokendb_project ({}) must both be set '
            'or both be empty'.format(props.tokendb_host, props.tokendb_project)
        )

    tokendb_host = api.checkout.gerrit_host().replace('-review.', '.')
    if props.tokendb_host:
        tokendb_host = '{}.googlesource.com'.format(props.tokendb_host)
    tokendb_project = props.tokendb_project or api.checkout.gerrit_project()

    # If the token database is in the top-level repo we just use that. If not
    # we need to checkout the repo even though it's already in our checkout.
    # It's much simpler to do a new checkout instead of parsing .gitmodules.
    tokendb_repo = api.checkout.root
    tokendb_branch = api.checkout.branch

    if props.tokendb_host and props.tokendb_project:
        tokendb_repo = api.path['start_dir'].join('tokendb')
        tokendb_remote = 'https://{}/{}'.format(
            tokendb_host.rstrip('/'), tokendb_project.strip('/')
        )
        tokendb_branch = props.tokendb_branch or "main"
        api.checkout(
            tokendb_remote,
            root=tokendb_repo,
            branch=tokendb_branch,
            use_trigger=False,
        )

    env = api.environment.init(api.checkout.root, props.environment_options)

    with env():
        api.build(api.checkout.root, props.build_options)

    tokendb_path = tokendb_repo.join(*re.split(r'/+', props.tokendb_path))

    if generated_tokendb_path != tokendb_path:
        api.file.copy('copy', generated_tokendb_path, tokendb_path)

    message = 'Update token db for commit {}'.format(
        api.checkout.revision[0:15]
    )

    change = api.auto_roller.attempt_roll(
        gerrit_host=tokendb_host,
        gerrit_project=tokendb_project,
        upstream_ref=tokendb_branch,
        repo_dir=tokendb_repo,
        commit_message=message,
        dry_run=props.dry_run,
        labels_to_set=api.roll_util.labels_to_set,
        labels_to_wait_on=api.roll_util.labels_to_wait_on,
        bot_commit=props.bot_commit,
    )

    return api.auto_roller.raw_result(change)


def GenTests(api):  # pylint: disable=invalid-name
    def properties(**kwargs):
        new_kwargs = {
            'steps': ['default'],
            'generated_tokendb_path': 'folder/generated.csv',
            'tokendb_path': 'tokendb.csv',
            'dry_run': False,
        }
        new_kwargs.update(api.checkout.git_properties())
        new_kwargs.update(kwargs)
        return api.properties(**new_kwargs)

    yield (
        api.status_check.test('simple')
        + properties()
        + api.auto_roller.success()
    )

    yield (
        api.status_check.test('dry-run')
        + properties(dry_run=True)
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test('separate-repo')
        + properties(tokendb_host='pigweed', tokendb_project='tokendb')
        + api.auto_roller.success()
    )
