# 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/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(
        api.auto_roller.Options(
            remote=props.remote,
            upstream_ref=props.branch,
            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,
        ),
        repo_dir=export_repo,
        commit_message='Update for {}'.format(checkout.revision()),
    )

    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()
    )
