import { time } from "../utils/DateUtils";
import { APIClient } from "./ApiClient";

export type RightVerb = "POST" | "GET" | "PUT" | "DELETE" | "PATCH";

export interface TokenRight {
  verb: RightVerb;
  path: string;
}

export interface APIToken {
  id: string;
  name: string;
  description: string;
  created: number;
  updated: number;
  rights: TokenRight[];
  last_used: number;
  ip_restriction?: string;
  max_inactivity?: number;
}

export function APITokenURL(t: APIToken, edit = false): string {
  return `/token/${t.id}${edit ? "/edit" : ""}`;
}

export function ExpiredAPIToken(t: APIToken): boolean {
  if (!t.max_inactivity) return false;
  return t.last_used + t.max_inactivity < time();
}

export interface APITokenPrivateKey {
  alg: string;
  priv: string;
}

export interface CreatedAPIToken {
  token: APIToken;
  priv_key: APITokenPrivateKey;
}

export class TokensApi {
  /**
   * Create a new API token
   */
  static async Create(n: APIToken): Promise<CreatedAPIToken> {
    return (
      await APIClient.exec({
        method: "POST",
        uri: "/token/create",
        jsonData: n,
      })
    ).data;
  }

  /**
   * Get the full list of tokens
   */
  static async GetList(): Promise<APIToken[]> {
    return (
      await APIClient.exec({
        method: "GET",
        uri: "/token/list",
      })
    ).data;
  }

  /**
   * Get the information about a single token
   */
  static async GetSingle(uuid: string): Promise<APIToken> {
    return (
      await APIClient.exec({
        method: "GET",
        uri: `/token/${uuid}`,
      })
    ).data;
  }

  /**
   * Update an existing API token information
   */
  static async Update(n: APIToken): Promise<void> {
    return (
      await APIClient.exec({
        method: "PATCH",
        uri: `/token/${n.id}`,
        jsonData: n,
      })
    ).data;
  }

  /**
   * Delete an API token
   */
  static async Delete(n: APIToken): Promise<void> {
    await APIClient.exec({
      method: "DELETE",
      uri: `/token/${n.id}`,
    });
  }
}