/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const { Octokit } = require("@octokit/rest");
const { REPO_OWNER, REPO } = require("./constants");

export interface Label {
  name: string;
}

export function getGitHubClient() {
  let auth = process.env["GITHUB_TOKEN"];
  if (!auth) {
    throw new Error(
      "No github token provided - process.env['GITHUB_TOKEN'] must be set."
    );
  }
  return new Octokit({ auth });
}

export async function addPrComment(pullNumber: number, body: string) {
  await getGitHubClient().rest.issues.createComment({
    owner: REPO_OWNER,
    repo: REPO,
    issue_number: pullNumber,
    body,
  });
}

export async function requestPrReviewers(
  pullNumber: number,
  reviewers: string[],
  githubClient?: any
) {
  if (!reviewers || reviewers.length === 0) {
    return;
  }
  const client = githubClient || getGitHubClient();
  for (const reviewer of reviewers) {
    try {
      await client.rest.pulls.requestReviewers({
        owner: REPO_OWNER,
        repo: REPO,
        pull_number: pullNumber,
        reviewers: [reviewer],
      });
    } catch (err) {
      console.log(
        `Unable to request review from ${reviewer} on PR ${pullNumber} (best effort): ${err}`
      );
    }
  }
}

export async function nextActionReviewers(
  pullNumber: number,
  existingLabels: Label[]
) {
  let newLabels = removeNextActionLabel(existingLabels);
  newLabels.push("Next Action: Reviewers");
  await getGitHubClient().rest.issues.setLabels({
    owner: REPO_OWNER,
    repo: REPO,
    issue_number: pullNumber,
    labels: newLabels,
  });
}

export async function nextActionAuthor(
  pullNumber: number,
  existingLabels: Label[]
) {
  let newLabels = removeNextActionLabel(existingLabels);
  newLabels.push("Next Action: Author");
  await getGitHubClient().rest.issues.setLabels({
    owner: REPO_OWNER,
    repo: REPO,
    issue_number: pullNumber,
    labels: newLabels,
  });
}

export async function closePr(pullNumber: number) {
  await getGitHubClient().rest.pulls.update({
    owner: REPO_OWNER,
    repo: REPO,
    pull_number: pullNumber,
    state: "closed",
  });
}

export async function getPrFiles(pullNumber: number): Promise<string[]> {
  const files = await getGitHubClient().paginate(
    getGitHubClient().rest.pulls.listFiles,
    {
      owner: REPO_OWNER,
      repo: REPO,
      pull_number: pullNumber,
    }
  );
  return files.map((file: any) => file.filename);
}

export async function checkIfCommitter(username: string): Promise<boolean> {
  const permissionLevel = (
    await getGitHubClient().rest.repos.getCollaboratorPermissionLevel({
      owner: REPO_OWNER,
      repo: REPO,
      username,
    })
  ).data;

  return (
    permissionLevel.permission === "write" ||
    permissionLevel.permission === "admin"
  );
}

export function getPullAuthorFromPayload(payload: any) {
  return payload.issue?.user?.login || payload.pull_request?.user?.login;
}

export function getPullNumberFromPayload(payload: any) {
  return payload.issue?.number || payload.pull_request?.number;
}

function removeNextActionLabel(existingLabels: Label[]): string[] {
  return existingLabels
    .filter(
      (label) =>
        label.name != "Next Action: Reviewers" &&
        label.name != "Next Action: Author"
    )
    .map((label) => label.name);
}

export function hasLabel(pull: any, labelName: string): boolean {
  return (pull?.labels || []).some(
    (label: any) =>
      (typeof label === "string" ? label : label?.name || "").toLowerCase() ===
      labelName.toLowerCase()
  );
}
