import * as plugins from './plugins.js';
import type { CloudlyApiClient } from './classes.cloudlyapiclient.js';
import { SecretGroup } from './classes.secretgroup.js';

export class SecretBundle implements plugins.servezoneInterfaces.data.ISecretBundle {
  // STATIC
  public static async getSecretBundleById(cloudlyClientRef: CloudlyApiClient, secretBundleIdArg: string) {
    const getSecretBundleByIdTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundleById>(
      'getSecretBundleById'
    );
    const response = await getSecretBundleByIdTR.fire({
      identity: cloudlyClientRef.identity,
      secretBundleId: secretBundleIdArg,
    });
    const newSecretBundle = new SecretBundle(cloudlyClientRef);
    Object.assign(newSecretBundle, response.secretBundle);
    return newSecretBundle;
  }

  public static async getSecretBundleByAuthorization(cloudlyClientRef: CloudlyApiClient, secretBundleAuthorizationArg: plugins.servezoneInterfaces.data.ISecretBundleAuthorization) {
    const getSecretBundleByAuthorizationTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundleByAuthorization>(
      'getSecretBundleByAuthorization'
    );
    const response = await getSecretBundleByAuthorizationTR.fire({
      identity: cloudlyClientRef.identity,
      secretBundleAuthorization: secretBundleAuthorizationArg,
    });
    const newSecretBundle = new SecretBundle(cloudlyClientRef);
    Object.assign(newSecretBundle, response.secretBundle);
    return newSecretBundle;
  }

  public static async getSecretBundles(cloudlyClientRef: CloudlyApiClient) {
    const getSecretBundlesTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundles>(
      'getSecretBundles'
    );
    const response = await getSecretBundlesTR.fire({
      identity: cloudlyClientRef.identity,
    });
    const secretBundles: SecretBundle[] = [];
    for (const secretBundle of response.secretBundles) {
      const newSecretBundle = new SecretBundle(cloudlyClientRef);
      Object.assign(newSecretBundle, secretBundle);
      secretBundles.push(newSecretBundle);
    }
    return secretBundles;
  }

  public static async createSecretBundle(cloudlyClientRef: CloudlyApiClient, secretBundleDataArg: Partial<plugins.servezoneInterfaces.data.ISecretBundle['data']>) {
    const createSecretBundleTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_CreateSecretBundle>(
      'createSecretBundle'
    );
    const response = await createSecretBundleTR.fire({
      identity: cloudlyClientRef.identity,
      secretBundle: {
        id: null,
        data: {
          name: secretBundleDataArg.name,
          description: secretBundleDataArg.description,
          type: secretBundleDataArg.type,
          authorizations: secretBundleDataArg.authorizations,
          imageClaims: secretBundleDataArg.imageClaims,
          includedSecretGroupIds: secretBundleDataArg.includedSecretGroupIds,
          includedTags: secretBundleDataArg.includedTags,
        },
      },
    });
    const newSecretBundle = new SecretBundle(cloudlyClientRef);
    Object.assign(newSecretBundle, response.resultSecretBundle);
    return newSecretBundle;
  }

  // INSTANCE

  public cloudlyClientRef: CloudlyApiClient;
  
  public id: string;
  public data: plugins.servezoneInterfaces.data.ISecretBundle['data'];

  constructor(cloudlyClientRef: CloudlyApiClient) {
    this.cloudlyClientRef = cloudlyClientRef;
  }

  public async update() {
    const updateSecretBundleTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_UpdateSecretBundle>(
      'updateSecretBundle'
    );
    const response = await updateSecretBundleTR.fire({
      identity: this.cloudlyClientRef.identity,
      secretBundle: {
        id: this.id,
        data: this.data,
      },
    });

    const resultSecretBundleData = response.resultSecretBundle.data;
    plugins.smartexpect.expect(resultSecretBundleData).toEqual(this.data);

    return this;
  }

  public async delete(cloudlyClientRef: CloudlyApiClient, secretBundleIdArg: string) {
    const deleteSecretBundleTR = cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_DeleteSecretBundleById>(
      'deleteSecretBundleById'
    );
    const response = await deleteSecretBundleTR.fire({
      identity: cloudlyClientRef.identity,
      secretBundleId: this.id,
    });
    plugins.smartexpect.expect(response.ok).toBeTrue();
    return null;
  }

  public async getFlatKeyValueObjectForEnvironment(environmentArg: string = 'production') {
    const bundleAuthorization = this.data.authorizations.find(authorization => {
      return authorization.environment === environmentArg;
    });
    if (bundleAuthorization) {
      throw new Error(`no matching environment >>${environmentArg} found in secret bundle`);
    }

    const getFlatKeyValueObjectTR = this.cloudlyClientRef.typedsocketClient.createTypedRequest<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetFlatKeyValueObject>(
      'getFlatKeyValueObject'
    );
    const response = await getFlatKeyValueObjectTR.fire({
      identity: this.cloudlyClientRef.identity,
      seccretBundleId: this.id,
      secretBundleAuthorization: bundleAuthorization,
    });

    const flatKeyValueObject: {[key: string]: string} = response.flatKeyValueObject;

    return flatKeyValueObject;
  }
}