# 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.
"""Recipe for running a specified script from."""

from typing import Callable, Generator
import re

from PB.recipes.pigweed.run_script import InputProperties
from recipe_engine import config_types, recipe_api, recipe_test_api

DEPS = [
    'pigweed/checkout',
    'pigweed/environment',
    'recipe_engine/context',
    'recipe_engine/properties',
    'recipe_engine/step',
]

PROPERTIES = InputProperties

_Command = list[str | config_types.Path]


def RunSteps(api: recipe_api.RecipeScriptApi, props: InputProperties) -> None:
    checkout: api.checkout.CheckoutContext = api.checkout(
        props.checkout_options
    )
    env: api.environment.Environment = api.environment.init(
        checkout, props.environment_options
    )

    cmd: _Command = [checkout.root / props.script]

    with env():
        for arg in props.arguments:
            repl: Callable[[re.Match], str] = lambda match: getattr(
                env, match.group(1)
            )
            arg: str = re.sub(r'\$([\w]+)', repl, arg)
            arg: str = re.sub(r'\$\{([\w]+)\}', repl, arg)
            cmd.append(arg)

        with api.context(cwd=checkout.root):
            api.step(f'run {props.script}', cmd)


def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
    def properties(**kwargs):
        props = InputProperties(**kwargs)
        props.checkout_options.CopyFrom(api.checkout.git_options())
        return api.properties(props)

    yield (
        api.test('run_script')
        + properties(script='foo/bar/run-tests.sh', arguments='foo bar'.split())
    )

    yield (
        api.test('variable_substitution')
        + properties(
            script='run-tests.sh',
            arguments='without=$PW_TEST_VAR with=${PW_TEST_VAR}'.split(),
        )
    )
