import os, subprocess, requests, re
from vars import headers, token, upstream_repo, upstream_url

class PushCpException(Exception):
    pass

def get_commit_id(pr_number, actor_name, action_event, api_repo_name):
    params = {"per_page": 100}
    response = requests.get(f'https://api.github.com/repos/{api_repo_name}/issues/{pr_number}/events', headers=headers, params=params)
    commit_id = None
    for event in response.json():
        if (event["actor"]["login"] in actor_name) and (event["commit_id"] != None) and (commit_id == None) and (event["event"] == action_event):
            commit_id = event["commit_id"]
        elif (event["actor"]["login"] in actor_name) and (event["commit_id"] != None) and (commit_id != None) and (event["event"] == action_event):
            print(f'PR#{pr_number} has multiple commits made by {actor_name}')
            raise SystemExit(0)
    if commit_id == None:
        print(f'PR#{pr_number} has NO commit made by {actor_name}')
        raise SystemExit(0)
    return commit_id

def get_reviewers(pr_number, api_repo_name, issues_data):
    if "pull_request" not in issues_data: return []
    r = requests.get(f'https://api.github.com/repos/{api_repo_name}/pulls/{pr_number}/reviews', headers=headers)
    if len(r.json()) == 0:
        print(f"PR#{pr_number} has no approver at all.")
        raise SystemExit(0)
    approvers_list = []
    for review in r.json():
        if review["state"] == "APPROVED": approvers_list.append(review["user"]["login"])
    if len(approvers_list) == 0:
        print(f"PR#{pr_number} has no approval from the approver(s).")
        raise SystemExit(0)
    return approvers_list

def extract_release_numbers_data(pr_number, api_repo_name):

    def get_milestoned_issues(milestones, pr_number):
        results= {}
        for milestone in milestones:
            params = {
                "milestone": milestone["number"]
            }
            r = requests.get(f'https://api.github.com/repos/{api_repo_name}/issues', headers=headers, params=params)
            for issue in r.json():
                if issue["body"] == f'Forked from #{pr_number}' and issue["state"] == "open":
                    results[milestone["title"]] = issue["number"]
                    break
        return results

    response_milestones = requests.get(f'https://api.github.com/repos/{api_repo_name}/milestones', headers=headers)
    all_milestones = list(map(lambda n: {"title": n["title"].split("release blockers")[0].replace(" ", ""), "number": n["number"]}, response_milestones.json()))
    milestoned_issues = get_milestoned_issues(all_milestones, pr_number)
    return milestoned_issues

def issue_comment(issue_number, body_content, api_repo_name, is_prod):
    if is_prod == True:
        subprocess.run(['git', 'remote', 'add', 'upstream', upstream_url])
        subprocess.run(['gh', 'repo', 'set-default', upstream_repo])
        subprocess.run(['gh', 'issue', 'comment', str(issue_number), '--body', body_content])
        subprocess.run(['git', 'remote', 'rm', 'upstream'])
        subprocess.run(['gh', 'repo', 'set-default', api_repo_name])
    else:
        subprocess.run(['gh', 'issue', 'comment', str(issue_number), '--body', body_content])

def update_lockfile(changed_files, has_conflicts):
    print("The lockfile(s) may need to be updated!")
    print(changed_files)
    std_out_bazel_version = subprocess.Popen(["../bazelisk-linux-amd64", "--version"], stdout=subprocess.PIPE)
    bazel_version_std_out = std_out_bazel_version.communicate()[0].decode()
    major_version_digit = int(re.findall(r"\d.\d.\d", bazel_version_std_out)[0].split(".")[0])

    if major_version_digit < 7:
        print("Warning: The .bazelversion is less than 7. Therefore, the lockfiles will not be updated...")
    else: 
        if has_conflicts == True:
            print("The file(s) has conflict(s)... We may need to accept all current changes first")
            subprocess.run(["git", "checkout", "--ours", "MODULE.bazel.lock", "src/test/tools/bzlmod/MODULE.bazel.lock"])
            subprocess.run(["git", "add", "."])

        if "src/test/tools/bzlmod/MODULE.bazel.lock" in changed_files:
            print("src/test/tools/bzlmod/MODULE.bazel.lock needs to be updated. This may take awhile... Please be patient.")
            subprocess.run(["../bazelisk-linux-amd64", "run", "//src/test/tools/bzlmod:update_default_lock_file"])
            subprocess.run(["git", "add", "."])

        print("Running:  bazelisk-linux-amd64 mod deps --lockfile_mode=update")
        subprocess.run(["../bazelisk-linux-amd64", "mod", "deps", "--lockfile_mode=update"])
        subprocess.run(["git", "add", "."])
        subprocess.run(['git', 'status'])

        if has_conflicts == True:
            print("There was conflict(s)... Running cherry-pick --continue")
            subprocess.run(["git", "-c", "core.editor=true", "cherry-pick", "--continue"])
        else:
            print("Committing the changes...")
            subprocess.run(["git", "commit", "-m", "Update lockfile(s)"])
        subprocess.run(['git', 'status'])

def cherry_pick(commit_id, release_branch_name, target_branch_name, requires_clone, requires_checkout, input_data):
    gh_cli_repo_name = f"{input_data['user_name']}/bazel"
    gh_cli_repo_url = f"git@github.com:{gh_cli_repo_name}.git"
    master_branch = input_data["master_branch"]
    user_name = input_data["user_name"]
    user_email = input_data["email"]

    def clone_and_sync_repo(gh_cli_repo_name, master_branch, release_branch_name, user_name, gh_cli_repo_url, user_email):
        print("Cloning and syncing the repo...")
        subprocess.run(['gh', 'repo', 'sync', gh_cli_repo_name, "-b", master_branch])
        subprocess.run(['gh', 'repo', 'sync', gh_cli_repo_name, "-b", release_branch_name])
        subprocess.run(['git', 'clone', f"https://{user_name}:{token}@github.com/{gh_cli_repo_name}.git"])
        subprocess.run(['git', 'config', '--global', 'user.name', user_name])
        subprocess.run(['git', 'config', '--global', 'user.email', user_email])
        os.chdir("bazel")
        subprocess.run(['git', 'remote', 'add', 'origin', gh_cli_repo_url])
        subprocess.run(['git', 'remote', '-v'])

    def checkout_release_number(release_branch_name, target_branch_name):
        subprocess.run(['git', 'fetch', '--all'])
        status_checkout_release = subprocess.run(['git', 'checkout', release_branch_name])
        
        # Create the new release branch from the upstream if not exists already.
        if status_checkout_release.returncode != 0:
            print(f"There is NO branch called {release_branch_name}...")
            print(f"Creating the {release_branch_name} from upstream, {upstream_url}")
            subprocess.run(['git', 'remote', 'add', 'upstream', upstream_url])
            subprocess.run(['git', 'remote', '-v'])
            subprocess.run(['git', 'fetch', 'upstream'])
            subprocess.run(['git', 'branch', release_branch_name, f"upstream/{release_branch_name}"])
            release_push_status = subprocess.run(['git', 'push', '--set-upstream', 'origin', release_branch_name])
            if release_push_status.returncode != 0:
                raise Exception(f"The branch, {release_branch_name}, may not exist. Please retry the cherry-pick after the branch is created.")
            subprocess.run(['git', 'remote', 'rm', 'upstream'])
            subprocess.run(['git', 'checkout', release_branch_name])
        status_checkout_target = subprocess.run(['git', 'checkout', '-b', target_branch_name])
        if status_checkout_target.returncode != 0: raise Exception(f"Cherry-pick was being attempted. But, it failed due to already existent branch called {target_branch_name}\ncc: @bazelbuild/triage")

    def run_cherry_pick(is_prod, commit_id, target_branch_name):
        changed_files = set(str(subprocess.Popen(["git", "diff-tree", "--no-commit-id", "--name-only", commit_id, "-r", "-m"], stdout=subprocess.PIPE).communicate()[0].decode()).split("\n"))
        changed_files.discard("")
        print(f"Cherry-picking the commit id {commit_id} in CP branch: {target_branch_name}")
        if is_prod == True:
            cherrypick_status = subprocess.run(['git', 'cherry-pick', commit_id])
        else:
            cherrypick_status = subprocess.run(['git', 'cherry-pick', '-m', '1', commit_id])

        lockfile_names = {"src/test/tools/bzlmod/MODULE.bazel.lock", "MODULE.bazel.lock"}
        unmerged_all_files = str(subprocess.Popen(["git", "diff", "--name-only", "--diff-filter=U"], stdout=subprocess.PIPE).communicate()[0].decode()).split("\n")
        unmerged_rest = [j for i,j in enumerate(unmerged_all_files) if j not in lockfile_names and j != ""]
 
        if cherrypick_status.returncode != 0:
            if len(unmerged_rest) == 0 and ("src/test/tools/bzlmod/MODULE.bazel.lock" in changed_files or "MODULE.bazel.lock" in changed_files):
                update_lockfile(changed_files, True)
            else:
                subprocess.run(['git', 'cherry-pick', '--skip'])
                raise Exception("Cherry-pick was attempted, but there may be merge conflict(s). Please resolve manually.\ncc: @bazelbuild/triage")
        elif cherrypick_status.returncode == 0 and ("src/test/tools/bzlmod/MODULE.bazel.lock" in changed_files or "MODULE.bazel.lock" in changed_files):
            update_lockfile(changed_files, False)
        
    if requires_clone == True: clone_and_sync_repo(gh_cli_repo_name, master_branch, release_branch_name, user_name, gh_cli_repo_url, user_email)
    if requires_checkout == True: checkout_release_number(release_branch_name, target_branch_name)
    run_cherry_pick(input_data["is_prod"], commit_id, target_branch_name)

def push_to_branch(target_branch_name):
    print(f"Pushing it to branch: {target_branch_name}")
    push_status = subprocess.run(['git', 'push', '--set-upstream', 'origin', target_branch_name])
    if push_status.returncode != 0: raise PushCpException(f"Cherry-pick was attempted, but failed to push. Please check if the branch, {target_branch_name}, already exists\ncc: @bazelbuild/triage")

def get_cherry_picked_pr_number(head_branch, release_branch):
    params = {
        "head": head_branch,
        "base": release_branch,
        "state": "open"
    }
    r = requests.get(f'https://api.github.com/repos/{upstream_repo}/pulls', headers=headers, params=params).json()
    if len(r) == 1: return r[0]["number"]
    else: raise Exception(f"Could not find the cherry-picked PR number \ncc: @bazelbuild/triage")

def create_pr(reviewers, release_number, labels, pr_title, pr_body, release_branch_name, target_branch_name, user_name):
    head_branch = f"{user_name}:{target_branch_name}"
    reviewers_str = ",".join(reviewers)
    labels_str = ",".join(labels)
    modified_pr_title = f"[{release_number}] {pr_title}" if f"[{release_number}]" not in pr_title else pr_title
    status_create_pr = subprocess.run(['gh', 'pr', 'create', "--repo", upstream_repo, "--title", modified_pr_title, "--body", pr_body, "--head", head_branch, "--base", release_branch_name,  '--label', labels_str, '--reviewer', reviewers_str])
    if status_create_pr.returncode == 0:
        cherry_picked_pr_number = get_cherry_picked_pr_number(head_branch, release_branch_name)
        return cherry_picked_pr_number
    else: raise Exception("PR failed to be created.")

def get_labels(pr_number, api_repo_name):
    r = requests.get(f'https://api.github.com/repos/{api_repo_name}/issues/{pr_number}/labels', headers=headers)
    labels_list = list(filter(lambda label: "area" in label or "team" in label, list(map(lambda x: x["name"], r.json()))))
    if "awaiting-review" not in labels_list: labels_list.append("awaiting-review")
    return labels_list

def get_pr_title_body(commit_id, api_repo_name):
    response_commit = requests.get(f"https://api.github.com/repos/{api_repo_name}/commits/{commit_id}")
    original_msg = response_commit.json()["commit"]["message"]
    pr_title = original_msg[:original_msg.index("\n\n")] if "\n\n" in original_msg else original_msg
    commit_str_body = f"Commit https://github.com/{api_repo_name}/commit/{commit_id}"
    pr_body = (original_msg[original_msg.index("\n\n") + 2:] if "\n\n" in original_msg else original_msg) + f"\n\n{commit_str_body}"
    return {"title": pr_title, "body": pr_body}

def get_middle_text(all_str, left_str, right_str):
    left_index = all_str.index(left_str) + len(left_str)
    if right_str == None:
        right_index = len(all_str)
    else:
        right_index = all_str.index(right_str)
    return all_str[left_index:right_index]