# 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',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
]

PROPERTIES = InputProperties


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()
    tokendb_remote = 'https://{}/{}'.format(
        tokendb_host.rstrip('/'), tokendb_project.strip('/')
    )

    # 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_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(
        props.auto_roller_options,
        repo_dir=tokendb_repo,
        commit_message=message,
    )

    return api.auto_roller.raw_result(change)


def GenTests(api):  # pylint: disable=invalid-name
    def properties(dry_run=False, **kwargs):
        new_kwargs = {
            'steps': ['default'],
            'generated_tokendb_path': 'folder/generated.csv',
            'tokendb_path': 'tokendb.csv',
        }
        new_kwargs.update(api.checkout.git_properties())
        new_kwargs.setdefault(
            'auto_roller_options',
            {'dry_run': dry_run, 'remote': api.checkout.pigweed_repo,},
        )
        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()
    )
