# 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 pinned versions of Python packages."""

import re

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

DEPS = [
    'fuchsia/auto_roller',
    'fuchsia/gerrit',
    'fuchsia/status_check',
    'pigweed/build',
    'pigweed/checkout',
    'pigweed/environment',
    'pigweed/roll_util',
    'recipe_engine/properties',
    'recipe_engine/step',
]

PROPERTIES = InputProperties

PYTHON_VERSION_COMPATIBILITY = "PY3"


def RunSteps(api, props):  # pylint: disable=invalid-name
    api.checkout()
    env = api.environment.init(
        api.checkout.root, props.environment_options, use_constraint_file=False,
    )

    with env():
        constraint_file = props.path_to_constraint_file
        if not constraint_file:
            api.build.gn_gen(api.checkout.root, props.build_options)

            # pw_build_PIP_CONSTRAINTS is a GN arg that points to a pip
            # constraint file. For more see
            # https://pigweed.googlesource.com/pigweed/pigweed/+/main/pw_build/python.gni
            gn_args = api.build.get_gn_args(
                checkout_root=api.checkout.root,
                test_data=[
                    {
                        'name': 'pw_build_PIP_CONSTRAINTS',
                        'current': {'value': ['//foo/bar/constraint.file']},
                    }
                ],
            )
            constraint_file = gn_args['pw_build_PIP_CONSTRAINTS']['current'][
                'value'
            ][0].strip('/')

        assert constraint_file

        # Write list of packages to constraint file.
        cmd = [
            'pw',
            'python-packages',
            'list',
            api.checkout.root.join(constraint_file),
        ]
        api.step('freeze package list', cmd)

    change = api.auto_roller.attempt_roll(
        gerrit_host=api.gerrit.host_from_remote_url(api.checkout.remote),
        gerrit_project=api.gerrit.project_from_remote_url(api.checkout.remote),
        upstream_ref=api.checkout.branch,
        repo_dir=api.checkout.root,
        commit_message='roll: Update Python package versions',
        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 = {'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()
    )
