/*
 * Copyright (c) Microsoft Corporation.
 * Licensed under the MIT License.
 *
 * Code generated by Microsoft (R) AutoRest Code Generator.
 * Changes may cause incorrect behavior and will be lost if the code is regenerated.
 */

import * as coreClient from "@azure/core-client";
import * as coreRestPipeline from "@azure/core-rest-pipeline";
import {
  PipelineRequest,
  PipelineResponse,
  SendRequest
} from "@azure/core-rest-pipeline";
import * as coreAuth from "@azure/core-auth";
import {
  ServersImpl,
  ReplicasImpl,
  BackupsImpl,
  FirewallRulesImpl,
  DatabasesImpl,
  ConfigurationsImpl,
  LocationBasedCapabilitiesImpl,
  CheckVirtualNetworkSubnetUsageImpl,
  CheckNameAvailabilityImpl,
  GetPrivateDnsZoneSuffixImpl,
  OperationsImpl
} from "./operations";
import {
  Servers,
  Replicas,
  Backups,
  FirewallRules,
  Databases,
  Configurations,
  LocationBasedCapabilities,
  CheckVirtualNetworkSubnetUsage,
  CheckNameAvailability,
  GetPrivateDnsZoneSuffix,
  Operations
} from "./operationsInterfaces";
import { MySQLManagementFlexibleServerClientOptionalParams } from "./models";

export class MySQLManagementFlexibleServerClient extends coreClient.ServiceClient {
  $host: string;
  apiVersion: string;
  subscriptionId: string;

  /**
   * Initializes a new instance of the MySQLManagementFlexibleServerClient class.
   * @param credentials Subscription credentials which uniquely identify client subscription.
   * @param subscriptionId The ID of the target subscription.
   * @param options The parameter options
   */
  constructor(
    credentials: coreAuth.TokenCredential,
    subscriptionId: string,
    options?: MySQLManagementFlexibleServerClientOptionalParams
  ) {
    if (credentials === undefined) {
      throw new Error("'credentials' cannot be null");
    }
    if (subscriptionId === undefined) {
      throw new Error("'subscriptionId' cannot be null");
    }

    // Initializing default values for options
    if (!options) {
      options = {};
    }
    const defaults: MySQLManagementFlexibleServerClientOptionalParams = {
      requestContentType: "application/json; charset=utf-8",
      credential: credentials
    };

    const packageDetails = `azsdk-js-arm-mysql-flexible/3.1.0`;
    const userAgentPrefix =
      options.userAgentOptions && options.userAgentOptions.userAgentPrefix
        ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
        : `${packageDetails}`;

    const optionsWithDefaults = {
      ...defaults,
      ...options,
      userAgentOptions: {
        userAgentPrefix
      },
      endpoint:
        options.endpoint ?? options.baseUri ?? "https://management.azure.com"
    };
    super(optionsWithDefaults);

    let bearerTokenAuthenticationPolicyFound: boolean = false;
    if (options?.pipeline && options.pipeline.getOrderedPolicies().length > 0) {
      const pipelinePolicies: coreRestPipeline.PipelinePolicy[] = options.pipeline.getOrderedPolicies();
      bearerTokenAuthenticationPolicyFound = pipelinePolicies.some(
        (pipelinePolicy) =>
          pipelinePolicy.name ===
          coreRestPipeline.bearerTokenAuthenticationPolicyName
      );
    }
    if (
      !options ||
      !options.pipeline ||
      options.pipeline.getOrderedPolicies().length == 0 ||
      !bearerTokenAuthenticationPolicyFound
    ) {
      this.pipeline.removePolicy({
        name: coreRestPipeline.bearerTokenAuthenticationPolicyName
      });
      this.pipeline.addPolicy(
        coreRestPipeline.bearerTokenAuthenticationPolicy({
          credential: credentials,
          scopes:
            optionsWithDefaults.credentialScopes ??
            `${optionsWithDefaults.endpoint}/.default`,
          challengeCallbacks: {
            authorizeRequestOnChallenge:
              coreClient.authorizeRequestOnClaimChallenge
          }
        })
      );
    }
    // Parameter assignments
    this.subscriptionId = subscriptionId;

    // Assigning values to Constant parameters
    this.$host = options.$host || "https://management.azure.com";
    this.apiVersion = options.apiVersion || "2021-05-01";
    this.servers = new ServersImpl(this);
    this.replicas = new ReplicasImpl(this);
    this.backups = new BackupsImpl(this);
    this.firewallRules = new FirewallRulesImpl(this);
    this.databases = new DatabasesImpl(this);
    this.configurations = new ConfigurationsImpl(this);
    this.locationBasedCapabilities = new LocationBasedCapabilitiesImpl(this);
    this.checkVirtualNetworkSubnetUsage = new CheckVirtualNetworkSubnetUsageImpl(
      this
    );
    this.checkNameAvailability = new CheckNameAvailabilityImpl(this);
    this.getPrivateDnsZoneSuffix = new GetPrivateDnsZoneSuffixImpl(this);
    this.operations = new OperationsImpl(this);
    this.addCustomApiVersionPolicy(options.apiVersion);
  }

  /** A function that adds a policy that sets the api-version (or equivalent) to reflect the library version. */
  private addCustomApiVersionPolicy(apiVersion?: string) {
    if (!apiVersion) {
      return;
    }
    const apiVersionPolicy = {
      name: "CustomApiVersionPolicy",
      async sendRequest(
        request: PipelineRequest,
        next: SendRequest
      ): Promise<PipelineResponse> {
        const param = request.url.split("?");
        if (param.length > 1) {
          const newParams = param[1].split("&").map((item) => {
            if (item.indexOf("api-version") > -1) {
              return "api-version=" + apiVersion;
            } else {
              return item;
            }
          });
          request.url = param[0] + "?" + newParams.join("&");
        }
        return next(request);
      }
    };
    this.pipeline.addPolicy(apiVersionPolicy);
  }

  servers: Servers;
  replicas: Replicas;
  backups: Backups;
  firewallRules: FirewallRules;
  databases: Databases;
  configurations: Configurations;
  locationBasedCapabilities: LocationBasedCapabilities;
  checkVirtualNetworkSubnetUsage: CheckVirtualNetworkSubnetUsage;
  checkNameAvailability: CheckNameAvailability;
  getPrivateDnsZoneSuffix: GetPrivateDnsZoneSuffix;
  operations: Operations;
}
