# 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.
"""Build a GN target and copy part of the build directory to another repo."""

from future.moves.urllib.parse import urlparse

from PB.recipes.pigweed.target_to_git import InputProperties
from PB.recipe_modules.pigweed.checkout.options import (
    Options as CheckoutOptions,
)

DEPS = [
    'fuchsia/auto_roller',
    'fuchsia/gerrit',
    '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):
    checkout = api.checkout(props.checkout_options)
    env = api.environment.init(checkout.root, props.environment_options)

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

    export_repo = api.path['start_dir'].join('export_repo')
    dest_checkout = api.checkout(
        CheckoutOptions(
            remote=props.remote,
            branch=props.branch or 'main',
            use_trigger=False,
        ),
        root=export_repo,
    )

    with api.step.nest('rm'):
        for entry in api.file.glob_paths(
            'glob',
            export_repo,
            '*',
            include_hidden=False,
            test_data=('pw_foo', 'pw_bar'),
        ):
            if 'OWNERS' not in api.path.basename(entry):
                api.file.rmtree(api.path.basename(entry), entry)

    with api.step.nest('mv'):
        for entry in api.file.glob_paths(
            'glob',
            api.build.dir.join(props.artifact_root),
            '*',
            test_data=('pw_foo', 'pw_bar'),
        ):
            api.file.move(api.path.basename(entry), entry, export_repo)

    with api.context(cwd=export_repo):
        api.git('git add --intent-to-add', 'add', '--intent-to-add', '.')

    change = api.auto_roller.attempt_roll(
        gerrit_host=api.gerrit.host_from_remote_url(props.remote),
        gerrit_project=urlparse(props.remote).path.strip('/'),
        upstream_ref=props.branch,
        repo_dir=export_repo,
        commit_message='Update for {}'.format(checkout.revision()),
        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
    yield (
        api.status_check.test('success')
        + api.properties(
            artifact_root='out/generated',
            remote='https://pigweed.googlesource.com/generated',
            dry_run=False,
            **api.checkout.git_properties()
        )
        + api.checkout.ci_test_data()
        + api.auto_roller.success()
    )
