#!/usr/bin/env python3
# Copyright (C) 2024-2025 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import argparse
import os
import sys

from webkitpy.safer_cpp.checkers import Checker


def parser():
    parser = argparse.ArgumentParser(
        description='Create a CSV file from safer CPP expectations',
        epilog='Example: create-csv-from-safer-cpp-expectations -p WebKit')

    parser.add_argument(
        '--project', '-p',
        choices=Checker.projects(),
        required=True,
        help='Specify which project expectations you want to update'
    )

    parser.add_argument(
        '--output-file', '-o',
        help='Specify the output file path'
    )

    return parser.parse_args()


def load_expectations(file_map, checker, project):
    with open(checker.expectations_path(project)) as expectations_file:
        for line in expectations_file:
            line = line.strip()
            file_map.setdefault(line, set())
            file_map[line].add(checker.name())


def main():
    args = parser()

    project = args.project
    file_map = {}

    output_file = open(args.output_file, 'w') if args.output_file else sys.stdout

    checker_list = []
    for checker in Checker.enumerate():
        load_expectations(file_map, checker, args.project)
        checker_list.append(checker.name())
    print(','.join([''] + checker_list), file=output_file)

    for file_name in sorted(list(file_map)):
        checker_set = file_map[file_name]
        row = [file_name]
        for checker_type in checker_list:
            row.append('Has Failures' if checker_type in checker_set else '')
        print(','.join(row), file=output_file)


if __name__ == '__main__':
    main()
