#!/usr/bin/env python3
#
# Copyright (c) 2022 Google LLC. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause

# quick hacky script to check patches if they are candidates for lts. it checks
# only the non-merge commits.

import os
import git
import re
import sys
import csv
import argparse
import json
import subprocess
from io import StringIO
from unidiff import PatchSet
from config import MESSAGE_TOKENS, CPU_PATH_TOKEN, CPU_ERRATA_TOKEN, DOC_PATH_TOKEN, DOC_ERRATA_TOKEN

global_debug = False
def debug_print(*args, **kwargs):
    global global_var
    if global_debug:
        print(*args, **kwargs)

def contains_re(pf, tok):
    for hnk in pf:
        for ln in hnk:
            if ln.is_context:
                continue
            # here means the line is either added or removed
            txt = ln.value.strip()
            if tok.search(txt) is not None:
                return True

    return False

def process_ps(ps):
    score = 0

    cpu_tok = re.compile(CPU_PATH_TOKEN)
    doc_tok = re.compile(DOC_PATH_TOKEN)

    for pf in ps:
        if pf.is_binary_file or not pf.is_modified_file:
            continue
        if cpu_tok.search(pf.path) is not None:
            debug_print("* change found in cpu path:", pf.path);
            cpu_tok = re.compile(CPU_ERRATA_TOKEN)
            if contains_re(pf, cpu_tok):
                score = score + 1
                debug_print("    found", CPU_ERRATA_TOKEN)

        if doc_tok.search(pf.path) is not None:
            debug_print("* change found in macros doc path:", pf.path);
            doc_tok = re.compile(DOC_ERRATA_TOKEN)
            if contains_re(pf, doc_tok):
                score = score + 1
                debug_print("    found", DOC_ERRATA_TOKEN)

    return score

def query_gerrit(gerrit_user, ssh_key_path, change_id):
    ssh_command = [
        "ssh",
        "-o", "UserKnownHostsFile=/dev/null",
        "-o", "StrictHostKeyChecking=no",
        "-o", "PubkeyAcceptedKeyTypes=+ssh-rsa",
        "-p", "29418",
        "-i", ssh_key_path,
        f"{gerrit_user}@review.trustedfirmware.org",
        f"gerrit query --format=JSON change:'{change_id}'",
        "repo:'TF-A/trusted-firmware-a'"
    ]

    try:
        result = subprocess.run(ssh_command, capture_output=True, text=True, check=True)
        output = result.stdout.strip().split("\n")
        changes = [json.loads(line) for line in output if line.strip()]
        # Create a dictionary with branch as key and URL as value
        branches_urls = {change["branch"]: change["url"] for change in changes if "branch" in change and "url" in change}
        return branches_urls

    except subprocess.CalledProcessError as e:
        print("Error executing SSH command:", e)
        return {}

# REBASE_DEPTH is number of commits from tip of the LTS branch that we need
# to check to find the commit that the current patch set is based on
REBASE_DEPTH = 20


## TODO: for case like 921081049ec3 where we need to refactor first for security
#       patch to be applied then we should:
#       1. find the security patch
#       2. from that patch find CVE number if any
#       3. look for all patches that contain that CVE number in commit message

## TODO: similar to errata macros and rst file additions, we have CVE macros and rst file
#       additions. so we can use similar logic for that.

## TODO: for security we should look for CVE numbed regex match and if found flag it
def main():
    at_least_one_match = False
    parser = argparse.ArgumentParser(prog="lts-triage.py", description="check patches for LTS candidacy")
    parser.add_argument("--repo", required=True, help="path to tf-a git repo")
    parser.add_argument("--csv_path", required=True, help="path including the filename for CSV file")
    parser.add_argument("--lts", required=True, help="LTS branch, ex. lts-v2.8")
    parser.add_argument("--gerrit_user", required=True, help="The user id to perform the Gerrit query")
    parser.add_argument("--ssh_keyfile", required=True, help="The SSH keyfile")
    parser.add_argument("--debug", help="print debug logs", action="store_true")

    args = parser.parse_args()
    lts_branch = args.lts
    gerrit_user = args.gerrit_user
    ssh_keyfile = args.ssh_keyfile
    global global_debug
    global_debug = args.debug

    csv_columns = ["index", "commit id in the integration branch", "commit summary",
                   "score", "Gerrit Change-Id", "patch link for the LTS branch",
                   "patch link for the integration branch"]
    csv_data = []
    idx = 1

    repo = git.Repo(args.repo)

    # collect the LTS hashes in a list
    lts_change_ids = set()  # Set to store Gerrit Change-Ids from the LTS branch

    for cmt in repo.iter_commits(lts_branch):
        # Extract Gerrit Change-Id from the commit message
        change_id_match = re.search(r'Change-Id:\s*(\w+)', cmt.message)
        if change_id_match:
            lts_change_ids.add(change_id_match.group(1))

        if len(lts_change_ids) >= REBASE_DEPTH:
            break

    for cmt in repo.iter_commits('integration'):
        score = 0

        # if we find a same Change-Id among the ones we collected from the LTS branch
        # then we have seen all the new patches in the integration branch, so we should exit.
        change_id_match = re.search(r'Change-Id:\s*(\w+)', cmt.message)
        if change_id_match:
            change_id = change_id_match.group(1)
            if change_id in lts_change_ids:
                print("## stopping because found common Gerrit Change-Id between the two branches: ", change_id)
                break;

        # don't process merge commits
        if len(cmt.parents) > 1:
            continue

        tok = re.compile(MESSAGE_TOKENS, re.IGNORECASE)
        if tok.search(cmt.message) is not None:
            debug_print("## commit message match")
            score = score + 1

        diff_text = repo.git.diff(cmt.hexsha + "~1", cmt.hexsha, ignore_blank_lines=True, ignore_space_at_eol=True)
        ps = PatchSet(StringIO(diff_text))
        debug_print("# score before process_ps:", score)
        score = score + process_ps(ps)
        debug_print("# score after process_ps:", score)

        ln = f"{cmt.summary}:    {score}"
        print(ln)

        if score > 0:
            gerrit_links = query_gerrit(gerrit_user, ssh_keyfile, change_id)
            # Append data to CSV
            csv_data.append({
                "index": idx,
                "commit id in the integration branch": cmt.hexsha,
                "commit summary": cmt.summary,
                "score": score,
                "Gerrit Change-Id": change_id,
                "patch link for the LTS branch": gerrit_links.get(lts_branch, "N/A"),
                "patch link for the integration branch": gerrit_links.get("integration", "N/A")
            })
            idx += 1
            at_least_one_match = True

    if at_least_one_match == True:
        try:
            with open(args.csv_path, "w", newline='') as csvfile:
                writer = csv.DictWriter(csvfile, fieldnames=csv_columns)
                writer.writeheader()
                for data in csv_data:
                    writer.writerow(data)
        except:
            print("\n\nERROR: Couldn't open CSV file due to error: ", sys.exc_info()[0])

if __name__ == '__main__':
    main()
