#!/usr/bin/env python3
# Copyright (C) 2024 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 os
import re
import argparse

from webkitpy.safer_cpp.checkers import Checker

EXPECTATION_LINE_RE = r'(\s*\[\s*(?P<platform>\w+)\s*\]\s*)?(?P<path>.+)'


def normalize_platform(platform):
    if not platform:
        return None
    platform = platform.lower()
    if platform == "mac" or platform == "macos":
        return "macOS"
    elif platform == "ios":
        return "iOS"
    return None


def parser():
    parser = argparse.ArgumentParser(description='Automated tooling for updating safer CPP expectations', epilog='Example: update-safer-cpp-expectations -p WebKit --RefCntblBaseVirtualDtor platform/Scrollbar.h --UncountedCallArgsChecker platform/ScrollAnimator.h')

    checkers_group = parser.add_argument_group('checker arguments', 'List files to update for each checker')
    for checker in Checker.enumerate():
        checker_name = checker.name()
        checkers_group.add_argument(f'--{checker_name}', type=str, nargs='+')

    parser.add_argument(
        '--project', '-p',
        choices=Checker.projects(),
        help='Specify which project expectations you want to update'
    )
    parser.add_argument(
        '--find-expectations', '-f',
        dest='expected_file',
        default=None,
        help='Check if the given file has expected failures'
    )
    parser.add_argument(
        '--add-expected-failures',
        dest='add',
        action='store_true',
        default=False,
        help='OVERRIDE: Add expected failures to the expectations files in SaferCPPExpectations'
    )
    parser.add_argument(
        '--unexpected-results-file', '-r',
        dest='unexpected_results_file',
        default=None,
        help='Path to unexpected results file'
    )
    parser.add_argument(
        '--platform',
        default=None,
        help='Mac or iOS'
    )
    return parser.parse_args()


def update_expectations_from_file(unexpected_results, project, add=False, platform=None):
    filename = os.path.basename(unexpected_results)
    if not project:
        projects = [p for p in Checker.projects() if p in filename]
        if projects:
            project = projects[0]
        else:
            print(f'Could not find a project to update. Please include the project in the filename or pass in the --project argument.')
            return
    print(f"{'Adding' if add else 'Removing'} unexpected failures in {project}...\n")
    with open(unexpected_results, 'r') as unexpected_contents:
        checker_type = None
        file_list = []
        for line in unexpected_contents:
            if '=>' in line:
                if checker_type and file_list:
                    print(checker_type, file_list)
                    modify_expectations_for_checker(Checker.find_checker_by_name(checker_type), file_list, project, add, platform)
                checker_type = line.split()[-1]
                file_list = []
                continue
            file_path = line.strip()
            if file_path:
                file_list.append(file_path)

        if checker_type and file_list:
            print(checker_type, file_list)
            modify_expectations_for_checker(Checker.find_checker_by_name(checker_type), file_list, project, add, platform)

    print(f'Please add any changes to your commit using `git add` and `git commit --amend`.')


def modify_expectations_for_checker(checker, unexpected_contents, project, add, platform):
    if normalize_platform(platform) not in [None, 'macOS', 'iOS']:
        print(f'Unknown platform: {platform}')
        return

    path_to_expectations = checker.expectations_path(project)
    expectation_relpath = os.path.relpath(path_to_expectations)
    checker_name = checker.name()
    expectation_map = {}
    with open(path_to_expectations) as expectations_file:
        expectation_line_re = re.compile(EXPECTATION_LINE_RE)
        comments = []
        for line in expectations_file.read().splitlines():
            if line.startswith('//') or line.startswith('#'):
                comments.append(line)
                continue
            match = expectation_line_re.match(line)
            if not match:
                print(f'Unexpected line in {expectation_relpath}: {line}')
                continue
            expectation_platform = match.group('platform')
            path = match.group('path')
            if path in expectation_map:
                if normalize_platform(platform) == 'macOS' and normalize_platform(platform) == 'iOS':
                    expectation_platform = None
                elif normalize_platform(platform) == 'macOS' and normalize_platform(platform) == 'iOS':
                    expectation_platform = None
                else:
                    print(f'Conflicting or duplicate line in {expectation_relpath}: {path}')
                    continue
            expectation_map[match.group('path')] = {'platform': expectation_platform, 'comments': comments}
            comments = []

    count = 0
    if add:
        for path in unexpected_contents:
            if path in expectation_map:
                expectation_platform = expectation_map[path]['platform']
                if normalize_platform(expectation_platform) == normalize_platform(platform):
                    print(f'Path is already present in {expectation_relpath}: {path}')
                    continue
                if normalize_platform(expectation_platform) not in [None, 'macOS', 'iOS']:
                    print(f'Unexpected platform in {expectation_relpath}: {expectation_platform}')
                    continue
                expectation_map[path]['platform'] = None
            else:
                expectation_map[path] = {'platform': normalize_platform(platform), 'comments': []}
            count += 1
        print(f'Added {count} files with issues.\n')
    else:
        for path in unexpected_contents:
            if path not in expectation_map:
                print(f'Path not found in {expectation_relpath}: {path}')
                continue
            if platform:
                expectation_platform = normalize_platform(expectation_map[path]['platform'])
                if expectation_platform not in [None, normalize_platform(platform)]:
                    print(f'Expectation not found in {expectation_relpath}: {path} for {normalized_platform(platform)}')
                    continue # Expectation is for another platform. We're done
                if expectation_platform == None:
                    # None means it currently applies to both. Keep the expectation for the other platform.
                    expectation_map[path]['platform'] = 'macOS' if normalize_platform(platform) == 'iOS' else 'iOS'
                else:
                    del expectation_map[path]
            else:
                del expectation_map[path]
            count += 1
        print(f'Removed {count} fixed files.\n')

    lines = []
    for path in sorted(expectation_map.keys()):
        platform = expectation_map[path]['platform']
        for comment in expectation_map[path]['comments']:
            lines.append(f'{comment}\n')
        lines.append(f'[ {platform} ] {path}\n' if platform else f'{path}\n')

    with open(path_to_expectations, 'w') as expectations_file:
        expectations_file.writelines(lines)

    print(f'Updated expectations for {checker_name}!')


def update_expectations(args, project, add, platform):
    if not project:
        print(f'Could not find a project to update. Please pass in the --project argument.')
        return
    print(f"{'Adding' if add else 'Removing'} unexpected failures in {project}...\n")
    for checker in Checker.enumerate():
        files_per_checker = args[checker.name()]
        if files_per_checker:
            modify_expectations_for_checker(checker, files_per_checker, project, add, platform)
    print(f'Please add any changes to your commit using `git add` and `git commit --amend`.')


'''
This currently checks against the files in your local checkout at SaferCPPExpectations.
Ensure that it is up-to-date before using this script.
'''
def is_expected_file(expected_file):
    print('This checks against local expectations. Ensure your checkout is up-to-date.\n')
    line = f'{expected_file}\n'
    issues = False
    for project in Checker.projects():
        for checker in Checker.enumerate():
            path_to_expectations = checker.expectations_path(project)
            with open(path_to_expectations, 'r') as f:
                expectations = f.read()
                if line in expectations:
                    if not issues:
                        print(f'{expected_file} has the following issues:')
                    issues = True
                    print(f'- {project} {checker.name()}')
    if not issues:
        print(f'{expected_file} has no known issues!')
    else:
        print('Follow this link for the latest results: https://build.webkit.org/#/builders?tags=%2BSafer&tags=%2BCPP\n')


def main():
    args = parser()
    if args.expected_file:
        is_expected_file(args.expected_file)
        return
    if args.add:
        print('WARNING: Adding expected failures. Please only add expected failures when you fix false negatives in our tools.')
        user_input = input('Are you sure you want to proceed? [y/N]: ') or 'N'
        if user_input[0].lower() != 'y':
            return
    if args.unexpected_results_file:
        update_expectations_from_file(args.unexpected_results_file, args.project, args.add, args.platform)
    else:
        update_expectations(vars(args), args.project, args.add, args.platform)


if __name__ == '__main__':
    main()
