# 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
from PB.recipe_modules.pigweed.checkout.options import (
    Options as CheckoutOptions,
)

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
    checkout = api.checkout(props.checkout_options)

    tokendb_branch = props.tokendb_branch or "main"
    generated_tokendb_path = 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 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 = checkout.gerrit_host().replace('-review.', '.')
    if props.tokendb_host:
        tokendb_host = '{}.googlesource.com'.format(props.tokendb_host)
    tokendb_project = props.tokendb_project or 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 = checkout.root
    tokendb_branch = checkout.options.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(
            CheckoutOptions(
                remote=tokendb_remote, branch=tokendb_branch, use_trigger=False
            ),
            root=tokendb_repo,
        )

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

    with env():
        api.build(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(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()
    )
