#!/usr/bin/env python
# Copyright 2022 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.
"""Generates a patch file for sources from Fuchsia's fit and stdcompat.

Run this script to update third_party/fuchsia/pigweed_adaptations.patch.
"""

from pathlib import Path
import re
import subprocess
import tempfile
from typing import Iterable, TextIO
from datetime import datetime

HEADER = f'''# Copyright {datetime.today().year} 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.

# DO NOT EDIT! This file is generated by {Path(__file__).name}.
#
# To make changes, update and run ./{Path(__file__).name}.

# Patch the fit::function implementation for use in Pigweed:
#
#   - Use PW_ASSERT instead of __builtin_abort.
#   - Temporarily disable sanitizers when invoking a function for b/241567321.
#
'''.encode()


def _read_files_list(file: TextIO) -> Iterable[str]:
    """Reads the files list from the copy.bara.sky file."""
    found_list = False

    for line in file:
        if found_list:
            yield line
            if line == ']\n':
                break
        else:
            if line == 'fuchsia_repo_files = [\n':
                found_list = True
                yield '['


def _clone_fuchsia(temp_path: Path) -> Path:
    subprocess.run(
        [
            'git',
            '-C',
            temp_path,
            'clone',
            '--depth',
            '1',
            'https://fuchsia.googlesource.com/fuchsia',
        ],
        check=True,
    )

    return temp_path / 'fuchsia'


def _read_files(script: Path) -> list[Path]:
    with script.open() as file:
        paths_list: list[str] = eval(  # pylint: disable=eval-used
            ''.join(_read_files_list(file))
        )
        return list(Path(p) for p in paths_list if 'lib/stdcompat/' not in p)


def _add_include_before_namespace(text: str, include: str) -> str:
    return text.replace(
        '\nnamespace ', f'\n#include "{include}"\n\nnamespace ', 1
    )


_ASSERT = re.compile(r'\bassert\(')


def _patch_assert(text: str) -> str:
    replaced = text.replace('__builtin_abort()', 'PW_ASSERT(false)')
    replaced = _ASSERT.sub('PW_ASSERT(', replaced)

    if replaced == text:
        return replaced

    return _add_include_before_namespace(replaced, 'pw_assert/assert.h')


_CONSTINIT = re.compile(r'\b__CONSTINIT\b')


def _patch_constinit(text: str) -> str:
    replaced = _CONSTINIT.sub('PW_CONSTINIT', text)

    if replaced == text:
        return text

    replaced = replaced.replace('#include <zircon/compiler.h>\n', '')
    return _add_include_before_namespace(
        replaced, "pw_polyfill/language_feature_macros.h"
    )


def _patch_invoke(file: Path, text: str) -> str:
    # Update internal/function.h only.
    if file.name != 'function.h' or file.parent.name != 'internal':
        return text

    return _add_include_before_namespace(text, 'pw_preprocessor/compiler.h')


def _ignore_errors(file: Path, text: str) -> str:
    # Only patch result.h for now
    if file.name != 'result.h':
        return text

    text = _add_include_before_namespace(text, 'pw_preprocessor/compiler.h')

    # Push the diagnostics before the namespace.
    new_lines = ['', 'PW_MODIFY_DIAGNOSTICS_PUSH();']
    for clang_diag in ['-Wshadow-field-in-constructor']:
        new_lines.append(
            f'PW_MODIFY_DIAGNOSTIC_CLANG(ignored, "{clang_diag}");'
        )
    new_lines.append('')
    new_lines.append('')

    text = text.replace('\nnamespace ', '\n'.join(new_lines) + 'namespace ', 1)

    # Pop the diagnostics before the include guard's #endif
    split_text = text.rsplit('\n#endif', 1)
    text = '\nPW_MODIFY_DIAGNOSTICS_POP();\n\n#endif'.join(split_text)
    return text


def _patch(file: Path) -> str | None:
    text = file.read_text()
    updated = _patch_assert(text)
    updated = _patch_constinit(updated)
    updated = _patch_invoke(file, updated)
    updated = _ignore_errors(file, updated)
    return None if text == updated else updated


def _main() -> None:
    output_path = Path(__file__).parent

    # Clone Fuchsia to a temp directory
    with tempfile.TemporaryDirectory() as directory:
        repo = _clone_fuchsia(Path(directory))

        # Read the files list from copy.bara.sky and patch those files.
        paths = _read_files(output_path / 'copy.bara.sky')
        for file in (repo / path for path in paths):
            if (text := _patch(file)) is not None:
                print('Patching', file)
                file.write_text(text)
                subprocess.run(['clang-format', '-i', file], check=True)

        # Create a diff for the changes.
        diff = subprocess.run(
            ['git', '-C', repo, 'diff'], stdout=subprocess.PIPE, check=True
        ).stdout
        for path in paths:
            diff = diff.replace(
                path.as_posix().encode(),
                Path('third_party/fuchsia/repo', path).as_posix().encode(),
            )

    # Write the diff to function.patch.
    with output_path.joinpath('pigweed_adaptations.patch').open('wb') as output:
        output.write(HEADER)

        for line in diff.splitlines(keepends=True):
            if line == b' \n':
                output.write(b'\n')
            elif not line.startswith(b'index '):  # drop line with Git hashes
                output.write(line)


if __name__ == '__main__':
    _main()
