#!/usr/bin/env python3

# Copyright 2025 Google LLC
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import difflib
import os
import shutil
import subprocess
import sys
import tempfile

# Third party dependencies necessary for Dawn to generate its version of the header.
THIRD_PARTY_DIR = os.path.join('third_party')
JINJA2_DIR = os.path.join('third_party', 'jinja2')
MARKUPSAFE_DIR = os.path.join('third_party', 'markupsafe')

# Dawn generator constants.
DAWN_GENERATOR = os.path.join('generator', 'dawn_json_generator.py')
DAWN_GENERATOR_TEMPLATE_DIR = os.path.join('generator', 'templates')
DAWN_JSON = os.path.join('src', 'dawn', 'dawn.json')
DAWN_WEBGPU_HEADER_TARGET = 'webgpu_headers'

# Upstream webgpu-header constants.
WEBGPU_HEADER = os.path.join('third_party', 'webgpu-headers', 'src',
                             'webgpu.h')

# Default output file locations.
DAWN_GENERATED_HEADER = os.path.join('webgpu-headers', 'webgpu.h')
WEBGPU_GENERATED_HEADER = os.path.join('webgpu-headers', 'webgpu_upstream.h')
GENERATED_DIFF = os.path.join('webgpu-headers', 'webgpu.h.diff')


# Helper that removes all comments from headers so that they can be diff-ed easier.
def _remove_comments(input_path, output_path):
    lines = []
    with open(input_path, 'r') as input:
        last_line_was_comment = False
        in_comment_block = False
        for line in input:
            stripped = line.strip()

            # If we are in a comment block, skip until we find the end.
            if in_comment_block:
                if stripped.endswith("*/"):
                    in_comment_block = False
                    last_line_was_comment = True
                continue

            # Drop empty lines directly following comments.
            if not stripped and last_line_was_comment:
                continue

            if stripped.startswith('//'):
                # Simple single line comment case, just skip the line.
                last_line_was_comment = True
                continue

            if stripped.startswith("/*") and stripped.endswith("*/"):
                # Simple single line comment with multi-line syntax, just skip the line.
                last_line_was_comment = True
                continue

            if stripped.startswith("/*") and "*/" not in stripped:
                # Otherwise, if we are a multi-line comment that isn't inlined.
                in_comment_block = True
                continue

            last_line_was_comment = False
            lines.append(line)

    with open(output_path, 'w') as output:
        for line in lines:
            output.write(line)


# Helper that just calls into Dawn's generators and generates webgpu.h without
# comments.
def _gen_dawn_header(dir):
    subprocess.check_call([
        sys.executable, DAWN_GENERATOR, '--template-dir',
        DAWN_GENERATOR_TEMPLATE_DIR, '--output-dir', dir, '--dawn-json',
        DAWN_JSON, '--targets', DAWN_WEBGPU_HEADER_TARGET, '--jinja2-path',
        JINJA2_DIR, '--markupsafe-path', MARKUPSAFE_DIR
    ])
    _remove_comments(os.path.join(dir, DAWN_GENERATED_HEADER),
                     os.path.join(dir, DAWN_GENERATED_HEADER))


# Helper that removes comments from the upstream webgpu.h file.
def _gen_webgpu_header(dir):
    _remove_comments(WEBGPU_HEADER, os.path.join(dir, WEBGPU_GENERATED_HEADER))


# Helper that generates the diff between the Dawn and upstream headers.
def _gen_header_diff(temp_dir, output_dir):
    _gen_dawn_header(temp_dir)
    _gen_webgpu_header(temp_dir)

    with open(os.path.join(temp_dir, DAWN_GENERATED_HEADER), 'r') as dawn_header, \
         open(os.path.join(temp_dir, WEBGPU_GENERATED_HEADER), 'r') as webgpu_header, \
         open(os.path.join(output_dir, GENERATED_DIFF), 'w') as diff_file:
        diff = difflib.unified_diff(webgpu_header.readlines(),
                                    dawn_header.readlines(),
                                    fromfile='webgpu_header',
                                    tofile='dawn_header', n=0)
        # Skip writing all the line numbers as these all change every time
        # anything in the file changes.
        for line in diff:
            if line.startswith('@@'):
                diff_file.writelines('@@\n')
            else:
                diff_file.writelines(line)


# Helper that verifies that all the necessary dependencies to run checks are
# available. If they are not, we just silently pass for now.
def _check_deps():
    if not os.path.isdir(JINJA2_DIR):
        print(
            f'Third party dependency jinja2 is not available at {JINJA2_DIR}')
        return False
    if not os.path.isdir(MARKUPSAFE_DIR):
        print(
            f'Third party dependency markupsafe is not available at {MARKUPSAFE_DIR}'
        )
        return False
    if not os.path.exists(WEBGPU_HEADER):
        print(
            f'Third party upstream webgpu.h is not available at {WEBGPU_HEADER}'
        )
        return False
    return True


def main(args):
    parser = argparse.ArgumentParser()
    parser.add_argument('action', choices=('gen', 'check'))
    options = parser.parse_args()

    if options.action == 'gen':
        with tempfile.TemporaryDirectory() as temp_dir:
            _gen_header_diff(temp_dir, THIRD_PARTY_DIR)
        return 0

    if options.action == 'check':
        if not _check_deps():
            return 0
        with tempfile.TemporaryDirectory() as temp_dir:
            _gen_header_diff(temp_dir, temp_dir)

            with open(os.path.join(temp_dir, GENERATED_DIFF), 'r') as temp_file, \
                 open(os.path.join(THIRD_PARTY_DIR, GENERATED_DIFF), 'r') as curr_file:
                diff = ''.join(
                    difflib.unified_diff(temp_file.readlines(),
                                         curr_file.readlines()))
                if diff:
                    print(
                        "Changes resulted in new diffs between Dawn's and the "
                        "upstream webgpu.h. Please re-run "
                        "'third_party/webgpu-headers/cli gen' manually and "
                        "verify/commit the new diffs in "
                        "'third_party/webgpu-headers/webgpu.h.diff' if the "
                        "changes are expected.")
                    return 1

        return 0


if __name__ == '__main__':
    sys.exit(main(sys.argv))
