# Copyright 2025 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.
"""Script to generate BUILD.bazel files for all SOCs in Zephyr."""

import argparse
from pathlib import Path
import subprocess
import sys


def convert(soc_root: str, output_root: str, vendor_name: str) -> bool:
    """Converts one vendor's soc directory to Bazel. Returns success or not."""
    script_to_run = 'convert_one_soc_directory.py'
    start_dir = soc_root + f'/{vendor_name}'
    output_dir = output_root + f'/{vendor_name}'
    args = ['--start_dir', start_dir, '--output_dir', output_dir]

    command = [sys.executable, script_to_run] + args

    try:
        # Execute the script in a new process
        # 'check=True' will raise a CalledProcessError if the script exits with a non-zero status
        subprocess.run(
            command,
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            timeout=2,
            text=True,
        )
        print(f'Successfully executed {script_to_run} for {vendor_name}')
        return True

    except subprocess.CalledProcessError as e:
        print(f'Error executing {script_to_run}:')
        print(f'STDOUT: {e.stdout}')
        print(f'STDERR: {e.stderr}')
    except subprocess.TimeoutExpired as e:
        print(f'{script_to_run} timed out for {vendor_name}.')
    except FileNotFoundError:
        print(f"Error: The script '{script_to_run}' was not found.")

    return False


def main():
    """Main entry point."""
    parser = argparse.ArgumentParser(
        description=(
            "Batch-convert Zephyr's CMakeLists.txt files in the entire soc/"
            ' directory to BUILD.bazel'
        )
    )
    parser.add_argument(
        '--soc_root',
        required=True,
        help=(
            'Zephyr SOC root to start conversion, should be /path/to/zephyr/soc'
        ),
    )
    parser.add_argument(
        '--output_dir',
        required=True,
        help=(
            'Output directory to hold converted BUILD.bazel files, e.g.'
            ' third_party/zephyr/soc'
        ),
    )
    args = parser.parse_args()

    soc_root = Path(args.soc_root)

    if soc_root.name != 'soc':
        raise ValueError(f'Invalid soc root. Should be /path/to/zephyr/soc')

    soc_vendors = []
    for child in soc_root.iterdir():
        if child.is_dir():
            soc_vendors.append(child.name)

    failed_vendors = []
    for soc_vendor in soc_vendors:
        if not convert(args.soc_root, args.output_dir, soc_vendor):
            failed_vendors.append(soc_vendor)

    if failed_vendors:
        print(
            "Failed to convert the following vendors's soc directories, please"
            ' convert manually using convert_one_soc_directory.py:'
        )
        for vendor in failed_vendors:
            print(vendor)


if __name__ == '__main__':
    main()
