# Copyright 2026 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.
"""Full test of workflows module."""

from __future__ import annotations

from collections.abc import Iterator

from recipe_engine import post_process, recipe_api, recipe_test_api

from PB.recipe_engine import result as result_pb

DEPS = [
    'pigweed/workflows',
    'recipe_engine/path',
    'recipe_engine/step',
]


def RunSteps(api: recipe_api.RecipeScriptApi) -> result_pb.RawResult | None:
    suite = api.workflows.load()
    api.step.empty('result', step_text=str(len(suite.builds)))
    return None


def GenTests(
    api: recipe_test_api.RecipeTestApi,
) -> Iterator[recipe_test_api.TestData]:
    yield api.test(
        'textproto',
        api.workflows.mock_file(
            filename='workflows.textproto',
            content='builds { name: "foo" }',
        ),
        api.post_check(post_process.StepTextEquals, 'result', '1'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'json',
        api.workflows.mock_file(
            filename='workflows.json',
            content='{"builds": [{"name": "foo"}]}',
        ),
        api.post_check(post_process.StepTextEquals, 'result', '1'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'yaml',
        api.workflows.mock_file(
            filename='workflows.yaml',
            content={'builds': [{'name': 'foo'}]},
        ),
        api.post_check(post_process.StepTextEquals, 'result', '1'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'toml',
        api.workflows.mock_file(
            filename='workflows.toml',
            content='[[builds]]\nname = "foo"\n',
        ),
        api.post_check(post_process.StepTextEquals, 'result', '1'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'default_mock_content',
        api.workflows.mock_file(filename='workflows.yaml'),
        api.post_check(post_process.StepTextEquals, 'result', '1'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'default_mock_toml',
        api.workflows.mock_file(filename='workflows.toml'),
        api.post_check(post_process.StepTextEquals, 'result', '1'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'default_mock_json',
        api.workflows.mock_file(filename='workflows.json'),
        api.post_check(post_process.StepTextEquals, 'result', '1'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'default_mock_textproto',
        api.workflows.mock_file(filename='workflows.textproto'),
        api.post_check(post_process.StepTextEquals, 'result', '1'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'no_file',
        api.post_process(post_process.DropExpectation),
        status='FAILURE',
    )

    yield api.test(
        'multiple_files',
        api.path.exists(
            api.path.start_dir / 'co' / 'workflows.json',
            api.path.start_dir / 'co' / 'workflows.yaml',
        ),
        api.post_process(post_process.DropExpectation),
        status='FAILURE',
    )

    yield api.test(
        'driver_options',
        api.workflows.mock_file(
            filename='workflows.json',
            content=(
                '{"builds": [{"name": "foo", "buildConfig": {"name": "cfg", '
                '"driverOptions": {"@type": '
                '"type.googleapis.com/pw.build.proto.BazelDriverOptions", '
                '"noTest": true}}}]}'
            ),
        ),
        api.post_check(post_process.StepTextEquals, 'result', '1'),
        api.post_process(post_process.DropExpectation),
    )
