/**
 * @license
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed 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.
 */

import {HttpMethod, RestPluginApi} from '@gerritcodereview/typescript-api/rest';
import {
  AccountDetailInfo,
  AccountInfo,
  BranchName,
  ChangeInfo,
  RepoName,
} from '@gerritcodereview/typescript-api/rest-api';

// TODO: Try to remove it. The ResponseError and getErrorMessage duplicates
// code from the gr-plugin-rest-api.ts. This code is required because
// we want custom error processing in some functions. For details see
// the original gr-plugin-rest-api.ts file/
class ResponseError extends Error {
  constructor(readonly response: Response) {
    super();
  }
}

export class ServerConfigurationError extends Error {
  constructor(msg: string) {
    super(msg);
  }
}

async function getErrorMessage(response: Response) {
  const text = await response.text();
  return text ? `${response.status}: ${text}` : `${response.status}`;
}

export enum MergeCommitStrategy {
  ALL_CHANGED_FILES = 'ALL_CHANGED_FILES',
  FILES_WITH_CONFLICT_RESOLUTION = 'FILES_WITH_CONFLICT_RESOLUTION',
}

export enum FallbackCodeOwners {
  NONE = 'NONE',
  ALL_USERS = 'ALL_USERS',
}

export interface GeneralInfo {
  file_extension?: string;
  merge_commit_strategy: MergeCommitStrategy;
  implicit_approvals?: boolean;
  override_info_url?: string;
  invalid_code_owner_config_info_url?: string;
  fallback_code_owners: FallbackCodeOwners;
}

export interface CodeOwnerBranchConfigInfo {
  general?: GeneralInfo;
  disabled?: boolean;
  backend_id?: string;
  required_approval?: Array<RequiredApprovalInfo>;
  override_approval?: Array<RequiredApprovalInfo>;
}

export interface RequiredApprovalInfo {
  label: string;
  value: number;
}

export enum ChangeType {
  ADDED = 'ADDED',
  MODIFIED = 'MODIFIED',
  DELETED = 'DELETED',
  RENAMED = 'RENAMED',
  COPIED = 'COPIED',
}

export enum OwnerStatus {
  INSUFFICIENT_REVIEWERS = 'INSUFFICIENT_REVIEWERS',
  PENDING = 'PENDING',
  APPROVED = 'APPROVED',
}
export interface PathCodeOwnerStatusInfo {
  path: string;
  status: OwnerStatus;
  reasons?: Array<string>;
}

export interface FileCodeOwnerStatusInfo {
  change_type: ChangeType;
  old_path_status?: PathCodeOwnerStatusInfo;
  new_path_status?: PathCodeOwnerStatusInfo;
}

export interface CodeOwnerStatusInfo {
  patch_set_number: number;
  file_code_owner_statuses: Array<FileCodeOwnerStatusInfo>;
  more?: boolean;
  accounts?: {[account_id: number]: AccountInfo};
}

export interface CodeOwnersStatusInfo {
  disabled?: boolean;
  disabled_branches?: Array<string>;
}

export interface CodeOwnerInfo {
  account?: AccountInfo;
  selected?: boolean;
}
export interface CodeOwnersInfo {
  code_owners: Array<CodeOwnerInfo>;
  owned_by_all_users?: boolean;
}

export interface FetchedOwner {
  owners?: CodeOwnersInfo;
  error?: unknown;
}

export interface FetchedFile {
  path: string;
  info: FetchedOwner;
  status?: string;
}

export interface OwnedPathInfo {
  path: string;
  owned?: boolean;
  owners?: Array<AccountInfo>;
}

export interface OwnedChangedFileInfo {
  new_path?: OwnedPathInfo;
  old_path?: OwnedPathInfo;
}

export interface OwnedPathsInfo {
  owned_changed_files?: Array<OwnedChangedFileInfo>;
}

function changeBaseURL(change: ChangeInfo): string {
  return `/changes/${encodeURIComponent(change.project)}~${change._number}`;
}

/**
 * Responsible for communicating with the rest-api
 *
 * @see resources/Documentation/rest-api.md
 */
export class CodeOwnersApi {
  constructor(readonly restApi: RestPluginApi) {}

  /**
   * Send a get request and provides custom response-code handling
   */
  private async get(url: string): Promise<unknown> {
    const errFn = (response?: Response | null, error?: Error) => {
      if (error) throw error;
      if (response) throw new ResponseError(response);
      throw new Error('Generic REST API error');
    };
    try {
      return await this.restApi.send(HttpMethod.GET, url, undefined, errFn);
    } catch (err) {
      if (err instanceof ResponseError && err.response.status === 409) {
        return getErrorMessage(err.response).then(msg => {
          throw new ServerConfigurationError(msg);
        });
      }
      throw err;
    }
  }

  /**
   * Returns a promise fetching the owner statuses for all files within the
   * change.
   *
   * @doc
   * https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#change-endpoints
   */
  listOwnerStatus(change: ChangeInfo): Promise<CodeOwnerStatusInfo> {
    return this.get(
      `${changeBaseURL(change)}/code_owners.status?limit=100000`
    ) as Promise<CodeOwnerStatusInfo>;
  }

  /**
   * Returns a promise fetching which files are owned by a given user as well
   * as which reviewers own which files.
   */
  listOwnedPaths(change: ChangeInfo, account: AccountInfo) {
    if (!account.email && !account._account_id)
      return Promise.resolve(undefined);
    const user = account.email ?? account._account_id;
    return this.get(
      `${changeBaseURL(
        change
      )}/revisions/current/owned_paths?user=${user}&limit=10000&check_reviewers`
    ) as Promise<OwnedPathsInfo>;
  }

  /**
   * Returns a promise fetching the owners for a given path.
   *
   * @doc
   * https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#list-code-owners-for-path-in-branch
   */
  listOwnersForPath(
    change: ChangeInfo,
    path: string,
    limit: number
  ): Promise<CodeOwnersInfo> {
    return this.get(
      `${changeBaseURL(change)}/revisions/current/code_owners` +
        `/${encodeURIComponent(path)}?limit=${limit}&o=DETAILS`
    ) as Promise<CodeOwnersInfo>;
  }

  /**
   * Returns a promise fetching the owners config for a given path.
   *
   * @doc
   * https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#branch-endpoints
   */
  getConfigForPath(project: string, branch: string, path: string) {
    return this.get(
      `/projects/${encodeURIComponent(project)}/` +
        `branches/${encodeURIComponent(branch)}/` +
        `code_owners.config/${encodeURIComponent(path)}`
    );
  }

  /**
   * Returns a promise fetching the owners config for a given branch.
   *
   * @doc
   * https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#branch-endpoints
   */
  async getBranchConfig(project: RepoName, branch: BranchName) {
    try {
      const config = (await this.get(
        `/projects/${encodeURIComponent(project)}/` +
          `branches/${encodeURIComponent(branch)}/` +
          'code_owners.branch_config'
      )) as CodeOwnerBranchConfigInfo;
      return config;
    } catch (err) {
      if (err instanceof ResponseError) {
        if (err.response.status === 404) {
          // The 404 error means that the branch doesn't exist and
          // the plugin should be disabled.
          return {disabled: true};
        }
        return getErrorMessage(err.response).then(msg => {
          throw new Error(msg);
        });
      }
      throw err;
    }
  }
}

/**
 * Wrapper around codeOwnerApi, sends each requests only once and then cache
 * the response. A new CodeOwnersCacheApi instance is created every time when a
 * new change object is assigned.
 * Gerrit never updates existing change object, but instead always assigns a new
 * change object. Particularly, a new change object is assigned when a change
 * is updated and user clicks reload toasts to see the updated change.
 * As a result, the lifetime of a cache is the same as a lifetime of an assigned
 * change object.
 * Periodical cache invalidation can lead to inconsistency in UI, i.e.
 * user can see the old reviewers list (reflects a state when a change was
 * loaded) and code-owners status for the current reviewer list. To avoid
 * this inconsistency, the cache doesn't invalidate.
 */
export class CodeOwnersCacheApi {
  private promises = new Map<string, Promise<unknown>>();

  constructor(
    private readonly codeOwnerApi: CodeOwnersApi,
    private readonly change: ChangeInfo
  ) {}

  private fetchOnce(
    cacheKey: string,
    asyncFn: () => Promise<unknown>
  ): Promise<unknown> {
    let promise = this.promises.get(cacheKey);
    if (promise) return promise;
    promise = asyncFn();
    this.promises.set(cacheKey, promise);
    return promise;
  }

  getAccount(): Promise<AccountDetailInfo | undefined> {
    return this.fetchOnce('getAccount', () => this.getAccountImpl()) as Promise<
      AccountDetailInfo | undefined
    >;
  }

  private async getAccountImpl() {
    const loggedIn = await this.codeOwnerApi.restApi.getLoggedIn();
    if (!loggedIn) return undefined;
    return await this.codeOwnerApi.restApi.getAccount();
  }

  listOwnerStatus(): Promise<CodeOwnerStatusInfo> {
    return this.fetchOnce('listOwnerStatus', () =>
      this.codeOwnerApi.listOwnerStatus(this.change)
    ) as Promise<CodeOwnerStatusInfo>;
  }

  async listOwnedPaths(): Promise<OwnedPathsInfo | undefined> {
    const account = await this.getAccount();
    if (!account) return undefined;
    return this.fetchOnce('listOwnedPaths', () =>
      this.codeOwnerApi.listOwnedPaths(this.change, account)
    ) as Promise<OwnedPathsInfo | undefined>;
  }

  getBranchConfig(): Promise<CodeOwnerBranchConfigInfo> {
    return this.fetchOnce('getBranchConfig', () =>
      this.codeOwnerApi.getBranchConfig(this.change.project, this.change.branch)
    ) as Promise<CodeOwnerBranchConfigInfo>;
  }
}
