/**
 * Copyright IBM Corp. 2024, 2025
 */
import { Product } from '@apic/api-model/package/Product.js';
import { BaseAsset, Metadata, Ref } from '../../common/models/base-asset.model.js';
import { FileAccessType } from './api-spec-handler.interface.js';
import { Plan } from '@apic/api-model/package/Plan.js';
import { Project } from '../../lfs/models/project.model.js';
import { VCSProject } from '../../vcs/models/vcs-project.model.js';
import { AssetInfo } from '../../lfs/models/asset-info.model.js';
import { VCSAssetInfo } from '../../vcs/models/vcs-asset-info.model.js';
import { Quota } from '@apic/api-model/package/Quota.js';
import { AssemblyCountLimitViewTable } from '../store/api-plans-product.store.model.js';
import { AssemblyRateLimitViewTable } from '../store/api-plans-product.store.model.js';
import { OperationsMetadata } from '../../lfs/models/asset-metadata.model.js';
import {
  OverridePlanMetadata,
  RateLimitTable,
} from '../../component-models/models/add-override-plan-quota.model.js';
import { APICProject } from '../../apic-mode/models/apic-project.model.js';
import { APICAssetInfo } from '../../apic-mode/models/apic-asset-info.model.js';
import {
  SqlInjectionFilterAction,
  DpNanoGatewayConfig,
  Property,
  HostAlias,
  DpNanoEnvironment,
  CountLimitDefs,
} from '../../component-models/models/dp-nano-gateway.model.js';
import { FormViewTableData } from '../../component-models/models/form-view-table-data.model.js';

export type PlanInfo = {
  productContent?: Product;
  planContent: Plan;
  planFile: FileAccessType;
};

export type QuotaInfo = {
  planContent: Plan;
  quotaContent: Quota;
  quotaFile: FileAccessType;
};

export interface IApiPlansProductHandler {
  createProduct(
    metadata: Metadata,
    subFolderPath?: string,
  ): Promise<FileAccessType>;
  addExisitingAPI(
    metadata: Metadata[],
    productFile: FileAccessType,
  ): Promise<Product>;
  addExistingPlanAPI(
    metadata: Metadata[],
    planFile: FileAccessType,
  ): Promise<any>;
  removeAPI(
    productFile: FileAccessType,
    apiMetadata: Metadata,
  ): Promise<Product>;
  removePlanAPI(planFile: FileAccessType, apiMetadata: Metadata): Promise<any>;
  removeAllAPIList(planFile: FileAccessType): Promise<any>;
  updateAPIWithOperation(
    planFile: FileAccessType,
    apiMetadata: Metadata,
    selectedOperations: OperationsMetadata[],
  ): Promise<any>;
  updatePlanApiWithRateLimits(
    planFile: FileAccessType,
    formData: OverridePlanMetadata
  ): Promise<any>;
  updateNanoGatewayPlanApiWithRateLimits(
    planFile: FileAccessType,
    formData: OverridePlanMetadata,
    rateLimits?: RateLimitTable[],
  ): Promise<any>;
  removeOverridePlanQuota(
    planFile: FileAccessType,
    apiMetadata?: Metadata,
    operationMethodAndPath?: string,
    gatewayType?: string,
  ): Promise<any>;
  addExisitingPlan(
    metadata: Metadata[],
    productFile: FileAccessType,
  ): Promise<Product>;
  addPlan(
    metadata: Metadata,
    productFile?: FileAccessType,
    subFolderPath?: string,
  ): Promise<PlanInfo>;
  removePlan(
    productFile: FileAccessType,
    apiMetadata: Metadata,
  ): Promise<Product>;
  getAPIInfoForProductAsset(
    productAsset: Product,
    projects: (Project | VCSProject | APICProject)[],
  ): Promise<Array<AssetInfo | VCSAssetInfo | APICAssetInfo | Ref>>;
  getPlanInfoForProductAsset(
    productAsset: Product,
    projects: (Project | VCSProject | APICProject)[],
  ): Promise<Array<AssetInfo | VCSAssetInfo | APICAssetInfo>>;
  getAPIInfoForPlanAsset(
    planAsset: Plan,
    projects: (Project | VCSProject | APICProject)[],
  ): Promise<Array<AssetInfo | VCSAssetInfo | APICAssetInfo>>;
  updatePlanMetadata(
    oldPlanInfo: Metadata,
    newPlanInfo: Metadata,
    projects: (Project | VCSProject | APICProject)[],
    productFile?: FileAccessType,
  ): Promise<PlanInfo>;
  updatePlan(
    updatedPlanContent: string,
    planFile: FileAccessType,
  ): Promise<void>;
  addQuota(
    metadata: Metadata,
    // spec: Quota_Spec,
    spec : any,
    planFile?: FileAccessType,
    aliasName?: string,
  ): Promise<QuotaInfo>;
  addExisitingQuota(
    metadata: Metadata,
    projects: (Project | VCSProject | APICProject)[],
    planFile: FileAccessType,
    aliasName?: string,
  ): Promise<QuotaInfo>;
  removeRateLimitInline(
    planFile: FileAccessType,
    rateLimitName: string,
  ): Promise<Plan>;
  updateMetadata(
    newProductInfo: Metadata,
    productFile: FileAccessType,
  ): Promise<BaseAsset>;
  updateQuota(
    updatedQuotaContent: string,
    quotaFile: FileAccessType,
  ): Promise<void>;
  getRateLimitForPlan(
    projects: (Project | VCSProject | APICProject)[],
    planAsset: BaseAsset,
  ): Promise<any>;
  removeRateLimitInline(
    planFile: FileAccessType,
    rateLimitName: string,
  ): Promise<Plan>;
  updateQuotaMetadata(
    oldQuotaInfo: Metadata,
    newQuotaInfo: Metadata,
    projects: (Project | VCSProject | APICProject)[],
    planFile: FileAccessType,
  ): Promise<QuotaInfo>;
  removeQuotaList(
    planFile: FileAccessType,
    quotaMetadata: Metadata,
  ): Promise<Plan>;
  getAssemblyCountLimitsForPlan(
    projects: (Project | VCSProject | APICProject)[],
    planAsset: BaseAsset,
  ): Promise<any>;
  getAssemblyRateLimitsForPlan(
    projects: (Project | VCSProject | APICProject)[],
    planAsset: BaseAsset,
  ): Promise<any>;
  addAssemblyCountLimit(
    planFile: FileAccessType,
    data: AssemblyCountLimitViewTable[],
  ): Promise<Plan>;
  addAssemblyRateLimit(
    planFile: FileAccessType,
    data: AssemblyRateLimitViewTable[],
  ): Promise<Plan>;
  updateAssemblyCountLimit(
    planFile: FileAccessType,
    oldData: AssemblyCountLimitViewTable,
    newData: AssemblyCountLimitViewTable,
  ): Promise<Plan>;
  updateAssemblyRateLimit(
    planFile: FileAccessType,
    oldData: AssemblyRateLimitViewTable,
    newData: AssemblyRateLimitViewTable,
  ): Promise<Plan>;
  removeAssemblyCountLimit(
    planFile: FileAccessType,
    countLimitName: string,
  ): Promise<Plan>;
  removeAssemblyRateLimit(
    planFile: FileAccessType,
    rateLimitName: string,
  ): Promise<Plan>;
  removeRateLimit(
    planFile: FileAccessType,
    rateLimitMetadata: Metadata,
  ): Promise<Plan>;
  updateRatelimitMetadata(
    oldRateLimitInfo: Metadata,
    newRatelimitInfo: Metadata,
    projects: (Project | VCSProject | APICProject)[],
    planFile: FileAccessType,
  ): Promise<QuotaInfo>;
  updateProductInfo(
    updatedProductInfo: string,
    productFile: FileAccessType,
  ): Promise<void>;
  getQuotaListForPlan(
    projects: (Project | VCSProject | APICProject)[],
    planAsset: BaseAsset,
  ): Promise<any>;

  addSqlInjectionFilter(
    filterTypeId: string,
    actionId: SqlInjectionFilterAction,
    productFile: FileAccessType,
  ): Promise<Product>;

  removeSqlInjectionFilter(
    filterTypeId: string,
    productFile: FileAccessType,
  ): Promise<Product>;

  getSQLInjectionFiltersDataFromProduct(
    productAsset: Product,
  ): Promise<FormViewTableData[]>;

  /**
   * Updates the DataPower Nano Gateway configuration in a product
   * @param dpNanoGatewayConfig Configuration options for the gateway
   * @param productFile The product file to update
   * @returns Updated product
   */
  updateDpNanoGatewayConfig(
    dpNanoGatewayConfig: DpNanoGatewayConfig,
    productFile: FileAccessType,
  ): Promise<Product>;

  /**
   * Adds a property to the dp-nano-gateway properties in a product
   * @param property The property to add
   * @param productFile The product file to update
   * @returns Updated product
   */
  addProperty(
    property: Property,
    productFile: FileAccessType,
  ): Promise<Product>;

  /**
   * Removes a property from the dp-nano-gateway properties in a product
   * @param propertyKey The key of the property to remove
   * @param productFile The product file to update
   * @returns Updated product
   */
  removeProperty(
    propertyKey: string,
    productFile: FileAccessType,
  ): Promise<Product>;

  /**
   * Gets properties data from a product
   * @param productAsset The product asset
   * @returns Array of properties
   */
  getPropertiesFromProduct(productAsset: Product): Promise<Property[]>;

  addHostAlias(
    hostAlias: HostAlias,
    productFile: FileAccessType,
  ): Promise<Product>;

  removeHostAlias(ip: string, productFile: FileAccessType): Promise<Product>;

  getHostAliasesFromProduct(productAsset: Product): Promise<HostAlias[]>;

  addDpNanoEnvironment(
    environment: DpNanoEnvironment,
    productFile: FileAccessType,
  ): Promise<Product>;

  removeDpNanoEnvironment(
    envName: string,
    productFile: FileAccessType,
  ): Promise<Product>;

  getDpEnvironmentFromProduct(
    productAsset: Product,
  ): Promise<DpNanoEnvironment[]>;
  
  /**
   * Gets count limit definitions from a plan
   * @param planAsset The plan asset
   * @returns Array of count limit definitions
   */
  getCountLimitDefListFromPlan(
    projects: (Project | VCSProject | APICProject)[],
    planAsset: Plan,
  ): Promise<CountLimitDefs[]>;
  
  /**
   * Add a count limit definition to the dp-nano-gateway configuration of a plan
   * @param countLimitDef The count limit definition metadata to add
   * @param aliasName The alias name for the count limit definition
   * @param planFile The plan file to update
   * @returns Updated plan
   */
  addCountLimitDef(
    countLimitDef: Metadata[],
    aliasName: string,
    planFile: FileAccessType,
  ): Promise<Plan>;
  
  /**
   * Remove a count limit definition from the dp-nano-gateway configuration of a plan
   * @param countLimitName The name of the count limit definition to remove
   * @param aliasName The alias name for the count limit definition
   * @param planFile The plan file to update
   * @returns Updated plan
   */
  removeCountLimitDef(
    countLimitDef: CountLimitDefs,
    aliasName: string,
    planFile: FileAccessType,
  ): Promise<Plan>;
}
