/**
 * LINE Messaging API
 * This document describes LINE Messaging API.
 *
 * The version of the OpenAPI document: 0.0.1
 *
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

/* tslint:disable:no-unused-locals */
import { AttachModuleResponse } from "../model/attachModuleResponse.js";

import * as Types from "../../types.js";
import { ensureJSON } from "../../utils.js";
import { Readable } from "node:stream";

import HTTPFetchClient, {
  convertResponseToReadable,
  mergeHeaders,
} from "../../http-fetch.js";

// ===============================================
// This file is autogenerated - Please do not edit
// ===============================================

interface httpClientConfig {
  baseURL?: string;
  channelAccessToken: string;
  defaultHeaders?: Record<string, string>;
}

export class LineModuleAttachClient {
  private httpClient: HTTPFetchClient;

  constructor(config: httpClientConfig) {
    const baseURL = config.baseURL || "https://manager.line.biz";
    const defaultHeaders = mergeHeaders(config.defaultHeaders, {
      Authorization: "Bearer " + config.channelAccessToken,
    });
    this.httpClient = new HTTPFetchClient({
      defaultHeaders: defaultHeaders,
      baseURL: baseURL,
    });
  }

  /**
   * Attach by operation of the module channel provider
   * @param grantType authorization_code
   * @param code Authorization code received from the LINE Platform.
   * @param redirectUri Specify the redirect_uri specified in the URL for authentication and authorization.
   * @param codeVerifier Specify when using PKCE (Proof Key for Code Exchange) defined in the OAuth 2.0 extension specification as a countermeasure against authorization code interception attacks.
   * @param clientId Instead of using Authorization header, you can use this parameter to specify the channel ID of the module channel. You can find the channel ID of the module channel in the LINE Developers Console.
   * @param clientSecret Instead of using Authorization header, you can use this parameter to specify the channel secret of the module channel. You can find the channel secret of the module channel in the LINE Developers Console.
   * @param region If you specified a value for region in the URL for authentication and authorization, specify the same value.
   * @param basicSearchId If you specified a value for basic_search_id in the URL for authentication and authorization, specify the same value.
   * @param scope If you specified a value for scope in the URL for authentication and authorization, specify the same value.
   * @param brandType If you specified a value for brand_type in the URL for authentication and authorization, specify the same value.
   *
   * @see <a href="https://developers.line.biz/en/reference/partner-docs/#link-attach-by-operation-module-channel-provider"> Documentation</a>
   */
  public async attachModule(
    grantType: string,
    code: string,
    redirectUri: string,
    codeVerifier?: string,
    clientId?: string,
    clientSecret?: string,
    region?: string,
    basicSearchId?: string,
    scope?: string,
    brandType?: string,
  ): Promise<AttachModuleResponse> {
    return (
      await this.attachModuleWithHttpInfo(
        grantType,
        code,
        redirectUri,
        codeVerifier,
        clientId,
        clientSecret,
        region,
        basicSearchId,
        scope,
        brandType,
      )
    ).body;
  }

  /**
   * Attach by operation of the module channel provider.
   * This method includes HttpInfo object to return additional information.
   * @param grantType authorization_code
   * @param code Authorization code received from the LINE Platform.
   * @param redirectUri Specify the redirect_uri specified in the URL for authentication and authorization.
   * @param codeVerifier Specify when using PKCE (Proof Key for Code Exchange) defined in the OAuth 2.0 extension specification as a countermeasure against authorization code interception attacks.
   * @param clientId Instead of using Authorization header, you can use this parameter to specify the channel ID of the module channel. You can find the channel ID of the module channel in the LINE Developers Console.
   * @param clientSecret Instead of using Authorization header, you can use this parameter to specify the channel secret of the module channel. You can find the channel secret of the module channel in the LINE Developers Console.
   * @param region If you specified a value for region in the URL for authentication and authorization, specify the same value.
   * @param basicSearchId If you specified a value for basic_search_id in the URL for authentication and authorization, specify the same value.
   * @param scope If you specified a value for scope in the URL for authentication and authorization, specify the same value.
   * @param brandType If you specified a value for brand_type in the URL for authentication and authorization, specify the same value.
   *
   * @see <a href="https://developers.line.biz/en/reference/partner-docs/#link-attach-by-operation-module-channel-provider"> Documentation</a>
   */
  public async attachModuleWithHttpInfo(
    grantType: string,
    code: string,
    redirectUri: string,
    codeVerifier?: string,
    clientId?: string,
    clientSecret?: string,
    region?: string,
    basicSearchId?: string,
    scope?: string,
    brandType?: string,
  ): Promise<Types.ApiResponseType<AttachModuleResponse>> {
    const formParams = {
      grant_type: grantType,
      code: code,
      redirect_uri: redirectUri,
      code_verifier: codeVerifier,
      client_id: clientId,
      client_secret: clientSecret,
      region: region,
      basic_search_id: basicSearchId,
      scope: scope,
      brand_type: brandType,
    };
    Object.keys(formParams).forEach((key: keyof typeof formParams) => {
      if (formParams[key] === undefined) {
        delete formParams[key];
      }
    });

    const res = await this.httpClient.postForm(
      "/module/auth/v1/token",
      formParams,
    );
    const text = await res.text();
    const parsedBody = text ? JSON.parse(text) : null;
    return { httpResponse: res, body: parsedBody };
  }
}
