// Copyright 2022 Luca Casonato. All rights reserved. MIT license.
/**
 * Cloud Product Registry API Client for Deno
 * ==========================================
 * 
 * cloudproductregistry.googleapis.com API.
 * 
 * Docs: https://docs.cloud.google.com/product-registry
 * Source: https://googleapis.deno.dev/v1/cloudproductregistry:v1.ts
 */

import { auth, CredentialsClient, GoogleAuth, request } from "/_/base@v1/mod.ts";
export { auth, GoogleAuth };
export type { CredentialsClient };

/**
 * cloudproductregistry.googleapis.com API.
 */
export class CloudProductRegistry {
  #client: CredentialsClient | undefined;
  #baseUrl: string;

  constructor(client?: CredentialsClient, baseUrl: string = "https://cloudproductregistry.googleapis.com/") {
    this.#client = client;
    this.#baseUrl = baseUrl;
  }

  /**
   * Gets details of a LogicalProduct.
   *
   * @param name Required. The name of the LogicalProduct to retrieve. Format: logicalProducts/{logical_product}
   */
  async logicalProductsGet(name: string): Promise<LogicalProduct> {
    const url = new URL(`${this.#baseUrl}v1/${ name }`);
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return data as LogicalProduct;
  }

  /**
   * Lists LogicalProducts matching given criteria.
   *
   */
  async logicalProductsList(opts: LogicalProductsListOptions = {}): Promise<ListLogicalProductsResponse> {
    const url = new URL(`${this.#baseUrl}v1/logicalProducts`);
    if (opts.filter !== undefined) {
      url.searchParams.append("filter", String(opts.filter));
    }
    if (opts.pageSize !== undefined) {
      url.searchParams.append("pageSize", String(opts.pageSize));
    }
    if (opts.pageToken !== undefined) {
      url.searchParams.append("pageToken", String(opts.pageToken));
    }
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return data as ListLogicalProductsResponse;
  }

  /**
   * Look up entities.
   *
   * @param lookupUri Required. Entity uri to look up. Supported Formats: logicalProducts/{logical_product} logicalProducts/{logical_product}/variants/{variant} productSuites/{product_suite}
   */
  async logicalProductsLookupEntity(lookupUri: string): Promise<LookupEntityResponse> {
    const url = new URL(`${this.#baseUrl}v1/${ lookupUri }:lookupEntity`);
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return data as LookupEntityResponse;
  }

  /**
   * Get details of a LogicalProductVariant.
   *
   * @param name Required. The name of the LogicalProductVariant to retrieve. Format: logicalProducts/{logical_product}/variants/{variant}
   */
  async logicalProductsVariantsGet(name: string): Promise<LogicalProductVariant> {
    const url = new URL(`${this.#baseUrl}v1/${ name }`);
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return data as LogicalProductVariant;
  }

  /**
   * Lists LogicalProductVariants matching given criteria.
   *
   * @param parent Required. Parent logical product id. Format: logicalProducts/{logical_product}
   */
  async logicalProductsVariantsList(parent: string, opts: LogicalProductsVariantsListOptions = {}): Promise<ListLogicalProductVariantsResponse> {
    const url = new URL(`${this.#baseUrl}v1/${ parent }/variants`);
    if (opts.pageSize !== undefined) {
      url.searchParams.append("pageSize", String(opts.pageSize));
    }
    if (opts.pageToken !== undefined) {
      url.searchParams.append("pageToken", String(opts.pageToken));
    }
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return data as ListLogicalProductVariantsResponse;
  }

  /**
   * Look up entities.
   *
   * @param lookupUri Required. Entity uri to look up. Supported Formats: logicalProducts/{logical_product} logicalProducts/{logical_product}/variants/{variant} productSuites/{product_suite}
   */
  async logicalProductsVariantsLookupEntity(lookupUri: string): Promise<LookupEntityResponse> {
    const url = new URL(`${this.#baseUrl}v1/${ lookupUri }:lookupEntity`);
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return data as LookupEntityResponse;
  }

  /**
   * Get details of a ProductSuite.
   *
   * @param name Required. The name of the ProductSuite to retrieve. Format: productSuites/{product_suite}
   */
  async productSuitesGet(name: string): Promise<ProductSuite> {
    const url = new URL(`${this.#baseUrl}v1/${ name }`);
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return data as ProductSuite;
  }

  /**
   * Lists ProductSuites.
   *
   */
  async productSuitesList(opts: ProductSuitesListOptions = {}): Promise<ListProductSuitesResponse> {
    const url = new URL(`${this.#baseUrl}v1/productSuites`);
    if (opts.pageSize !== undefined) {
      url.searchParams.append("pageSize", String(opts.pageSize));
    }
    if (opts.pageToken !== undefined) {
      url.searchParams.append("pageToken", String(opts.pageToken));
    }
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return data as ListProductSuitesResponse;
  }

  /**
   * Look up entities.
   *
   * @param lookupUri Required. Entity uri to look up. Supported Formats: logicalProducts/{logical_product} logicalProducts/{logical_product}/variants/{variant} productSuites/{product_suite}
   */
  async productSuitesLookupEntity(lookupUri: string): Promise<LookupEntityResponse> {
    const url = new URL(`${this.#baseUrl}v1/${ lookupUri }:lookupEntity`);
    const data = await request(url.href, {
      client: this.#client,
      method: "GET",
    });
    return data as LookupEntityResponse;
  }
}

/**
 * Response message for ListLogicalProducts.
 */
export interface ListLogicalProductsResponse {
  /**
   * Matched LogicalProducts
   */
  logicalProducts?: LogicalProduct[];
  /**
   * A token, which can be sent as `page_token` to retrieve the next page. If
   * this field is omitted, there are no subsequent pages.
   */
  nextPageToken?: string;
}

/**
 * Response message for ListLogicalProductVariants.
 */
export interface ListLogicalProductVariantsResponse {
  /**
   * Matched LogicalProductVariants
   */
  logicalProductVariants?: LogicalProductVariant[];
  /**
   * A token, which can be sent as `page_token` to retrieve the next page. If
   * this field is omitted, there are no subsequent pages.
   */
  nextPageToken?: string;
}

/**
 * Response message for ListProductSuites.
 */
export interface ListProductSuitesResponse {
  /**
   * A token, which can be sent as `page_token` to retrieve the next page. If
   * this field is omitted, there are no subsequent pages.
   */
  nextPageToken?: string;
  /**
   * Matched ProductSuites
   */
  productSuites?: ProductSuite[];
}

/**
 * Represents an independent service offering that can be provisioned by a
 * customer.
 */
export interface LogicalProduct {
  /**
   * Output only. Current Lifecycle state of the logical product.
   */
  readonly lifecycleState?:  | "LIFECYCLE_STATE_UNSPECIFIED" | "LIFECYCLE_STATE_PUBLIC_PREVIEW" | "LIFECYCLE_STATE_PRIVATE_GA" | "LIFECYCLE_STATE_GA" | "LIFECYCLE_STATE_DEPRECATED";
  /**
   * Identifier. The resource name of the LogicalProduct. Format:
   * logicalProducts/{logical_product}.
   */
  name?: string;
  /**
   * Product suite associated with the logical product. Format:
   * productSuites/{product_suite}.
   */
  productSuite?: string;
  /**
   * Output only. Indicates whether the logical product has been replaced. If
   * `false`, the product is active. If `true`, the product has been replaced by
   * another type, and the `replacement` field contains the resource name of
   * that replacement.
   */
  readonly replaced?: boolean;
  /**
   * Output only. The resource name of the Logical Entity that the logical
   * product is replaced by. This field is only populated when this logical
   * product is replaced by some other type. Eg:
   * logicalProducts/{logical_product}/variants/{variant},
   * productSuites/{product_suite}, etc.
   */
  readonly replacement?: string;
  /**
   * Display name of the LogicalProduct.
   */
  title?: string;
  /**
   * Output only. Child variant resource references. Format:
   * logicalProducts/{logical_product}/variants/{variant}
   */
  readonly variants?: string[];
}

/**
 * Additional options for CloudProductRegistry#logicalProductsList.
 */
export interface LogicalProductsListOptions {
  /**
   * Optional. The filter expression for listing logical products. Filter
   * syntax: https://google.aip.dev/160 Supported fields: suite_id
   */
  filter?: string;
  /**
   * Optional. The maximum number of logical products to return. The service
   * may return fewer than this value. If unspecified, at most 100 logical
   * products will be returned. The maximum value is 500; values above 500 will
   * be coerced to 500.
   */
  pageSize?: number;
  /**
   * Optional. A page token, received from a previous `ListLogicalProducts`
   * call. Provide this to retrieve the subsequent page. When paginating, all
   * other parameters provided to `ListLogicalProducts` must match the call that
   * provided the page token.
   */
  pageToken?: string;
}

/**
 * Additional options for CloudProductRegistry#logicalProductsVariantsList.
 */
export interface LogicalProductsVariantsListOptions {
  /**
   * Optional. The maximum number of logical product variants to return. The
   * service may return fewer than this value. If unspecified, at most 100
   * logical product variants will be returned. The maximum value is 500; values
   * above 500 will be coerced to 500.
   */
  pageSize?: number;
  /**
   * Optional. A page token, received from a previous
   * `ListLogicalProductVariants` call. Provide this to retrieve the subsequent
   * page. When paginating, all other parameters provided to
   * `ListLogicalProductVariants` must match the call that provided the page
   * token.
   */
  pageToken?: string;
}

/**
 * Represents a distinct offering derived from a primary product that retains
 * core functionalities but offers specialized features for a specific market
 * segment.
 */
export interface LogicalProductVariant {
  /**
   * Output only. Current Lifecycle state of the logical product variant.
   */
  readonly lifecycleState?:  | "LIFECYCLE_STATE_UNSPECIFIED" | "LIFECYCLE_STATE_PUBLIC_PREVIEW" | "LIFECYCLE_STATE_PRIVATE_GA" | "LIFECYCLE_STATE_GA" | "LIFECYCLE_STATE_DEPRECATED";
  /**
   * Identifier. The resource name of the LogicalProductVariant. Format:
   * logicalProducts/{logical_product}/variants/{variant}
   */
  name?: string;
  /**
   * Output only. Indicates whether the logical product variant has been
   * replaced. If `false`, the variant is active. If `true`, the variant has
   * been replaced by another type, and the `replacement` field contains the
   * resource name of that replacement.
   */
  readonly replaced?: boolean;
  /**
   * Output only. The resource name of the Logical Entity that the logical
   * product variant is replaced by. This field is only populated when this
   * logical product variant is replaced by some other type. Eg:
   * logicalProducts/{logical_product}, productSuites/{product_suite}, etc.
   */
  readonly replacement?: string;
  /**
   * Display name of the LogicalProductVariant.
   */
  title?: string;
}

/**
 * Response message for LookupEntity.
 */
export interface LookupEntityResponse {
  /**
   * Matched LogicalProduct.
   */
  logicalProduct?: LogicalProduct;
  /**
   * Matched LogicalProductVariant.
   */
  logicalProductVariant?: LogicalProductVariant;
  /**
   * Matched ProductSuite.
   */
  productSuite?: ProductSuite;
}

/**
 * Represents a unified grouping of products sharing a common brand and market
 * positioning.
 */
export interface ProductSuite {
  /**
   * Output only. LogicalProducts under this suite. Format:
   * logicalProducts/{logical_product}
   */
  readonly logicalProducts?: string[];
  /**
   * Identifier. The resource name of the ProductSuite. Format:
   * productSuites/{product_suite}
   */
  name?: string;
  /**
   * Output only. Indicates whether the product suite has been replaced. If
   * `false`, the product suite is active. If `true`, the product suite has been
   * replaced by another type, and the `replacement` field contains the resource
   * name of that replacement.
   */
  readonly replaced?: boolean;
  /**
   * Output only. The resource name of the Logical Entity that the product
   * suite is replaced by. This field is only populated when this product suite
   * is replaced by some other type. Eg: logicalProducts/{logical_product},
   * logicalProducts/{logical_product}/variants/{variant}, etc.
   */
  readonly replacement?: string;
  /**
   * Title of the ProductSuite.
   */
  title?: string;
}

/**
 * Additional options for CloudProductRegistry#productSuitesList.
 */
export interface ProductSuitesListOptions {
  /**
   * Optional. The maximum number of suites to return. The service may return
   * fewer than this value. If unspecified, at most 100 suites will be returned.
   * The maximum value is 500; values above 500 will be coerced to 500.
   */
  pageSize?: number;
  /**
   * Optional. A page token, received from a previous `ListProductSuites` call.
   * Provide this to retrieve the subsequent page. When paginating, all other
   * parameters provided to `ListProductSuites` must match the call that
   * provided the page token.
   */
  pageToken?: string;
}