const axios = require("axios");
const { 
    debug,
    getEnvOrThrow,
} = require("../utils");

const KYMA_SERVICE_ID = "47c9dcbf-ff30-448e-ab36-d3bad66ba281";

class KEBConfig {
  static fromEnv() {
    return new KEBConfig(
      getEnvOrThrow("KEB_HOST"),
      getEnvOrThrow("KEB_CLIENT_ID"),
      getEnvOrThrow("KEB_CLIENT_SECRET"),
      getEnvOrThrow("KEB_GLOBALACCOUNT_ID"),
      getEnvOrThrow("KEB_SUBACCOUNT_ID"),
      getEnvOrThrow("KEB_PLAN_ID"),
    );
  }

  constructor(host, clientID, clientSecret, globalAccountID, subaccountID, planID) {
    this.host = host;
    this.clientID = clientID;
    this.clientSecret = clientSecret;
    this.globalAccountID = globalAccountID;
    this.subaccountID = subaccountID;
    this.planID = planID;
  }
}
  

class KEBClient {
  constructor(config) {
    this.host = config.host;
    this.clientID = config.clientID;
    this.clientSecret = config.clientSecret;
    this.globalAccountID = config.globalAccountID;
    this.subaccountID = config.subaccountID;
    this.planID = config.planID
    this.serviceID = KYMA_SERVICE_ID;
    
    this._token = undefined;
  }

  async getToken() {
    if (!this._token || this._token.expires_at < +new Date()) {
      const url = `https://oauth2.${this.host}/oauth2/token`;
      const scopes = ["broker:write", "cld:read"];
      const body = `grant_type=client_credentials&scope=${scopes.join(" ")}`;
      const params = {
        auth: {
          username: this.clientID,
          password: this.clientSecret,
        },
      };

      try {
        const resp = await axios.post(url, body, params);

        this._token = resp.data;
        this._token.expires_at = (+new Date() + this._token.expires_in * 1000);
      } catch (err) {
        const msg = "Error when requesting bearer token from KCP";
        if (err.response) {
          throw new Error(
            `${msg}: ${err.response.status} ${err.response.statusText}`
          );
        } else {
          throw new Error(`${msg}: ${err.toString()}`);
        }
      }
    }

    return this._token.access_token;
  }

  async buildRequest(payload, endpoint, verb) {
    const token = await this.getToken();
    const url = `https://kyma-env-broker.${this.host}/oauth/v2/${endpoint}`;
    const headers = {
      "X-Broker-API-Version": 2.14,
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json",
    };

    const request = {
      url: url,
      method: verb,
      headers: headers,
      data: payload,
    };
    return request;
  }

  async callKEB(payload, endpoint, verb) {
    const config = await this.buildRequest(payload, endpoint, verb);

    const msg = "Error calling KEB";
    try {
      const resp = await axios.request(config);
      if (resp.data.errors) {
        debug(resp);
        throw new Error(resp.data);
      }
      return resp.data;
    } catch (err) {
      debug(err);
      if (err.response) {
        throw new Error(
          `${msg}: ${err.response.status} ${err.response.statusText}`
        );
      } else {
        throw new Error(`${msg}: ${err.toString()}`);
      }
    }
  }

  async provisionSKR(name, instanceID) {
    const payload = {
      service_id: this.serviceID,
      plan_id: this.planID,
      context: {
        globalaccount_id: this.globalAccountID,
        subaccount_id: this.subaccountID,
      },
      parameters: {
        name: name,
      },
    };
    const endpoint = `service_instances/${instanceID}`;
    try {
      return await this.callKEB(payload, endpoint, "put");
    } catch (err) {
      throw new Error(`error while provisioning SKR: ${err.toString()}`);
    }
  }

  async getOperation(instanceID, operationID) {
    const endpoint = `service_instances/${instanceID}/last_operation?operation=${operationID}`;
    try {
      return await this.callKEB({}, endpoint, "get");
    } catch (err) {
      debug(err.toString())
      return new Error(`error while checking SKR State: ${err.toString()}`);
    }
  }

  async deprovisionSKR(instanceID) {
    const endpoint = `service_instances/${instanceID}?service_id=${this.serviceID}&plan_id=${this.planID}`;
    try {
      return await this.callKEB(null, endpoint, "delete");
    } catch (err) {
      return new Error(`error while deprovisioning SKR: ${err.toString()}`);
    }
  }
}

module.exports = {
  KEBConfig,
  KEBClient,
};

@@ -32,17 +32,16 @@
 %0Aconst %7B
- 
 %0A    deb
@@ -451,24 +451,53 @@
 _PLAN_ID%22),%0A
+      process.env.KEB_REGION%0A
     );%0A  %7D%0A%0A
@@ -577,16 +577,24 @@
 , planID
+, region
 ) %7B%0A    
@@ -791,16 +791,40 @@
 ID;%0A
+    this.region = region;%0A
   %7D%0A%7D%0A
-  
 %0A%0Acl
@@ -1144,16 +1144,45 @@
 ID;%0A    
+this.region = config.region;%0A
 %0A    thi
@@ -2260,16 +2260,53 @@
 oken();%0A
+    const region = this.getRegion();%0A
     cons
@@ -2357,16 +2357,25 @@
 %7D/oauth/
+$%7Bregion%7D
 v2/$%7Bend
@@ -4440,24 +4440,142 @@
 );%0A    %7D%0A  %7D
+%0A%0A  getRegion() %7B%0A    if (this.region && this.region != %22%22) %7B%0A      return %60$%7Bthis.region%7D/%60;%0A    %7D%0A    return %22%22;%0A  %7D
 %0A%7D%0A%0Amodule.e

Add region to fast integration KEB client (#11242)