/**
 * @license
 * Copyright (C) 2024 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,
  ChangeInfo,
  NumericChangeId,
  RepoName,
} from '@gerritcodereview/typescript-api/rest-api';
import {User, UserRole} from './owners-model';

export interface GroupOwner {
  name: string;
}

export interface Owner extends GroupOwner {
  id: number;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function isOwner(o: any): o is Owner {
  return o && typeof o.id === 'number' && typeof o.name === 'string';
}

export type FileOwner = Owner | GroupOwner;

export interface OwnedFiles {
  [fileName: string]: FileOwner[];
}

export interface OwnersLabels {
  [id: string]: {
    [label: string]: number;
  };
}

export interface FilesOwners {
  files: OwnedFiles;
  files_approved: OwnedFiles;
  files_auto_approved?: OwnedFiles;
  owners_labels: OwnersLabels;
}

const OWNERS_SUBMIT_REQUIREMENT = 'has:approval_owners';
const OWNERS_SUBMIT_RULE = 'owners~OwnersSubmitRequirement';

export function hasOwnersSubmitRequirement(change: ChangeInfo): boolean {
  return (
    change.submit_requirements !== undefined &&
    change.submit_requirements.find(r => {
      const expression = r.submittability_expression_result.expression;
      return (
        expression.includes(OWNERS_SUBMIT_REQUIREMENT) ||
        expression.includes(OWNERS_SUBMIT_RULE)
      );
    }) !== undefined
  );
}

class ResponseError extends Error {
  constructor(readonly response: Response) {
    super();
  }
}

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

class OwnersApi {
  constructor(readonly restApi: RestPluginApi) {}

  async getAccount(): Promise<AccountDetailInfo | undefined> {
    const loggedIn = await this.restApi.getLoggedIn();
    if (!loggedIn) return undefined;
    return await this.restApi.getAccount();
  }

  /**
   * Returns the list of owners associated to each file that needs a review or were approved,
   * and, for each owner, its current labels and votes.
   *
   * @doc
   * https://gerrit.googlesource.com/plugins/owners/+/refs/heads/master/owners/src/main/resources/Documentation/rest-api.md
   */
  getFilesOwners(
    repoName: RepoName,
    changeId: NumericChangeId,
    revision: String
  ): Promise<FilesOwners> {
    return this.get(
      `/changes/${encodeURIComponent(
        repoName
      )}~${changeId}/revisions/${revision}/owners~files-owners`
    ) as Promise<FilesOwners>;
  }

  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) {
        getErrorMessage(err.response).then(msg => {
          // TODO handle 409 in UI - show banner with error
          console.error(`Plugin configuration errot: ${msg}`);
        });
      }
      throw err;
    }
  }
}

/**
 * Calls to REST API can be safely cached cuz:
 * 1. Gerrit doesn't update the existing change object but obtains and passes new instead
 * 2. `OwnersService.getOwnersService` guarantees that whenever new change object is retrieved the new service instance is created (and cache is created with it)
 */
class OwnersApiCache {
  private loggedInUser?: Promise<User>;

  private filesOwners?: Promise<FilesOwners | undefined>;

  constructor(
    private readonly api: OwnersApi,
    private readonly change: ChangeInfo
  ) {}

  getLoggedInUser(): Promise<User> {
    if (this.loggedInUser === undefined) {
      this.loggedInUser = this.getLoggedInUserImpl();
    }
    return this.loggedInUser;
  }

  getFilesOwners(): Promise<FilesOwners | undefined> {
    if (this.filesOwners === undefined) {
      this.filesOwners = this.getFilesOwnersImpl();
    }
    return this.filesOwners;
  }

  private async getLoggedInUserImpl(): Promise<User> {
    const account = await this.api.getAccount();
    if (!account) {
      return {role: UserRole.ANONYMOUS} as unknown as User;
    }
    const role =
      this.change.owner._account_id === account._account_id
        ? UserRole.CHANGE_OWNER
        : UserRole.OTHER;
    return {account, role} as unknown as User;
  }

  private async getFilesOwnersImpl(): Promise<FilesOwners | undefined> {
    return this.api.getFilesOwners(
      this.change.project,
      this.change._number,
      this.change.current_revision ?? 'current'
    );
  }
}

let service: OwnersService | undefined;

export class OwnersService {
  private apiCache: OwnersApiCache;

  constructor(readonly restApi: RestPluginApi, readonly change: ChangeInfo) {
    this.apiCache = new OwnersApiCache(new OwnersApi(restApi), change);
  }

  getLoggedInUser(): Promise<User> {
    return this.apiCache.getLoggedInUser();
  }

  getFilesOwners(): Promise<FilesOwners | undefined> {
    return this.apiCache.getFilesOwners();
  }

  static getOwnersService(restApi: RestPluginApi, change: ChangeInfo) {
    if (!service || service.change !== change) {
      service = new OwnersService(restApi, change);
    }
    return service;
  }
}
