# 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 one soc/<vendor> directory."""

import argparse
from pathlib import Path
import subprocess
import sys
import cmake_converter_common as common
import soc_cmake_to_bazel


def is_leaf(cmake_dir: Path) -> bool:
    """Checks if a directory is a leaf SoC directory."""
    # common directory does not represent a real SoC.
    if cmake_dir.name == 'common':
        return False
    for item in cmake_dir.iterdir():
        if item.is_dir():
            if next(item.rglob('CMakeLists.txt'), None):
                return False
    return True


def main():
    """Main entry point."""
    parser = argparse.ArgumentParser(
        description=(
            "Batch-convert Zephyr's CMakeLists.txt files in one soc/<vendor>"
            ' directory to BUILD.bazel'
        )
    )
    parser.add_argument(
        '--start_dir',
        required=True,
        help='Top-level SoC directory to start conversion, e.g. soc/atmel',
    )
    parser.add_argument(
        '--output_dir',
        required=True,
        help=(
            'Output directory to hold converted BUILD.bazel files, e.g.'
            ' third_party/zephyr/soc/atmel'
        ),
    )
    args = parser.parse_args()

    start_path = Path(args.start_dir)
    output_path = Path(args.output_dir)

    try:
        any_cmake_file = next(start_path.rglob('CMakeLists.txt'))
        soc_root = soc_cmake_to_bazel.find_soc_root(any_cmake_file)
    except (StopIteration, ValueError) as e:
        print(
            f"Error: No CMakeLists.txt found in '{args.start_dir}' "
            "or it's not a Zephyr SoC directory.",
            file=sys.stderr,
        )
        print(f'Details: {e}', file=sys.stderr)
        sys.exit(1)

    if start_path.parent != soc_root:
        print(
            f"Warning: '{start_path}' is not a top-level SoC directory "
            'e.g. soc/atmel. Converted Bazel rules may miss common files '
            'in the top-level SoC directory.'
        )

    cmake_files = sorted(list(start_path.rglob('CMakeLists.txt')))

    for cmake_file in cmake_files:
        cmake_dir = cmake_file.parent
        output_dir = common.translate_relative_path(
            cmake_dir, start_path, output_path
        )
        output_dir.mkdir(parents=True, exist_ok=True)
        output_file = output_dir / 'BUILD.bazel'

        print(f'Converting {cmake_file} to {output_file}...')

        with open(cmake_file, 'r', encoding='utf-8') as f:
            cmake_content = f.read()

        target_name = cmake_dir.name
        skip_parent = False
        if target_name == 'common' or cmake_dir == start_path:
            skip_parent = True
        parent_cmake_file = next(cmake_dir.parent.glob('CMakeLists.txt'), None)
        if not parent_cmake_file:
            skip_parent = True

        parent_filegroup_name, common_filegroup_names = (
            soc_cmake_to_bazel.get_filegroup_names(cmake_file, skip_parent)
        )

        leaf = is_leaf(cmake_dir)

        path_transformer = soc_cmake_to_bazel.get_path_transformer(
            Path(cmake_file).parent
        )
        bazel_content = soc_cmake_to_bazel.convert_cmakelists_to_bazel(
            cmake_content,
            target_name,
            leaf,
            parent_filegroup_name,
            common_filegroup_names,
            path_transformer=path_transformer,
        )

        with open(output_file, 'w', encoding='utf-8') as f:
            f.write(bazel_content)

        try:
            subprocess.run(['buildifier', str(output_file)], check=True)
        except subprocess.CalledProcessError as e:
            print(
                f'Warning: failed to run buildifier on {output_file}: {e}',
                file=sys.stderr,
            )
        except FileNotFoundError:
            print('Warning: buildifier not found in PATH', file=sys.stderr)

        # Write an empty header file alongside the generated BUILD.bazel so that
        # our generated filegroups are never empty.
        empty_header_file = output_dir / 'empty.h'
        with open(empty_header_file, 'w') as f:
            f.write("""// 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.
""")

    print('Conversion complete.')


if __name__ == '__main__':
    main()
