#!/usr/bin/env python3

# Copyright (C) 2022 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.
# 3.  Neither the name of Apple Inc. ("Apple") nor the names of
#     its contributors may be used to endorse or promote products derived
#     from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY APPLE 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 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.

# Script to generate compile_commands.json file

import re
import os
import sys
import glob
import json
import argparse

# Get command line args
parser = argparse.ArgumentParser(description='Generate compile_commands.json', 
            usage="""
                  make r EXPORT_COMPILE_COMMANDS=YES
                  generate-compile-commands WebKitBuild/Release

                  https://trac.webkit.org/wiki/Clangd
                  """)

parser.add_argument('built_products_dir', help='path to the build directory containing generated compile commands (ex: WebKitBuild/Release)')
opts = parser.parse_args()

# Change to the root of WebKit Directory
file_dir = os.path.dirname(os.path.realpath(__file__))
base_dir = file_dir + "/../../"
os.chdir(base_dir)

# Check compile_commands folder exists
compile_commands_dir = opts.built_products_dir + "/compile_commands/"

if not os.path.exists(compile_commands_dir):
    print("Please specify the build directory with compile_commands.")
    print("Example: generate-compile-commands WebKitBuild/Release")
    exit(1)

# Generate compile_commands.json

# For things not to horribly break for users during normal use we need to validate the compiler is spitting out
# valid json files. Sometimes if a compile error happens or the user stops the build part way through
# there will be a very invalid json file sitting in the directory. When we go to bundle it up into the final
# compile_commands.json file, we now have an invalid compile_commands.json file and clangd will not work.
# To prevent this from happening we should check that every json file we add is valid, and also ensure there are no 
# duplicate entries. We will build a map of all the valid files.

# Key   - JSON file contents
# Value - Timestamp contents
files = dict()

# Do not index third party code.
# Most people probably do not need it.
third_party_regex = re.compile('Source/ThirdParty')

for j_file_name in glob.glob(compile_commands_dir + "/*.json"):
    j_file = open(j_file_name, "r")
    json_contents = j_file.read()

    if third_party_regex.search(json_contents):
        continue

    # -2 gets rid of the comma at the end of the file.
    json_contents = json_contents[:-2]

    # Try to load JSON File
    try:
        json.loads(json_contents)
    except Exception:
        print("Invalid JSON File: " + j_file_name)
        continue

    # Validate if the json file already exists in the map.
    if json_contents in files:
        pass
    else:
        files[json_contents] = os.path.getmtime(j_file_name)

# Remove any previous compile_commands.json
try:
    os.remove("compile_commands.json")
except Exception:
    pass

# Write the new compile_commands.json file
new_compile_commands_file = open("compile_commands.json", 'w')
new_compile_commands_file.write("[")

for index, key in enumerate(files.keys()):
    if index != 0:
        new_compile_commands_file.write(",\n")
    else:
        new_compile_commands_file.write("\n")
    new_compile_commands_file.write(key)

new_compile_commands_file.write("\n]\n")
new_compile_commands_file.close()

print("Generated Compile Commands!")
