"use strict";
const Controller = require("egg").Controller;

class ProxyController extends Controller {
  async info() {
    const { ctx } = this;
    const { params } = ctx;

    ctx.body = {
      name: `hello ${params.id}`,
    };
  }

  addToken(options) {
    const { ctx } = this;
    const { session, headers, ip } = ctx;

    if (
      session.passport &&
      session.passport.user &&
      session.passport.user &&
      session.passport.user.token
    ) {
      options.headers["Authorization"] =
        "Bearer " + session.passport.user.token;
    }

    if (headers["device-id"]) {
      options.headers["Device-Id"] = headers["device-id"];
    }

    if (ip) {
      options.headers["Client-Ip"] = ip;
    }

    return options;
  }

  splitUrl(fullUrl) {
    const { config } = this;
    const { prefix } = config;

    if (prefix && prefix.length > 1) {
      fullUrl = fullUrl.substring(prefix.length - 1);
    }

    return fullUrl.substring(4);
  }

  addParams(options) {
    const { ctx } = this;
    const postData = !ctx.body ? "" : JSON.stringify(ctx.body || {});

    options.params = postData;
  }

  addContentLength(options) {
    const { params, headers } = options;

    if (params) {
      headers["Content-Length"] = params.length;
    }
  }

  getOptions(url, type) {
    const { config,ctx,logger } = this;
    const {  session } = ctx;
    const { access_token } = session.user_info;
    const { restful = {} } = config;
    const { version, host, port } = restful;
    logger.info(version,'version')
    const catalog = url.substring(1, url.indexOf("/", 1));
    const pathUrl = url.substring(url.indexOf("/", 1));
    const fullPath = "/" + catalog + version + pathUrl;

    return {
      host: host, //后台请求地址
      port: port,
      path: fullPath,
      method: type,
      agent: false,
      headers: {
        authorization: `Bearer ${access_token}`,
        Accept: "application/json",
        "Content-Type": "application/json",
        // "User-Agent": "Request for Express",
      },
    };
  }

  async get() {
    const { ctx, logger } = this;
    const { originalUrl,  } = ctx;
    const url = this.splitUrl(originalUrl);
    const options = this.getOptions(url, 'GET');
    const {host ,port,path,...rest} = options
    const result = await ctx.curl(`${host}:${port}${path}`, {
      ...rest,
      timeout: [5000, 60000],
    });
    ctx.body = result.data|| {};

    return ctx.body;
  }

  async post() {
    const { ctx, config, logger } = this;
    const { originalUrl, session, curl, request } = ctx;
    const { restful = {} } = config;
    const { host } = restful;
    const { access_token } = session.user_info;
    const url = this.splitUrl(originalUrl);
    const options = this.getOptions(url, "POST");

    this.addToken(options);
    addParams(options);

    const result = await curl(`${host}${url}`, {
      method: "POST",
      dataType: "json",
      data: JSON.stringify(request.body),
      headers: {
        authorization: `Bearer ${access_token}`,
        accept: "application/json",
        "content-type": "application/json",
      },
    });

    logger.info(
      "post proxy url:",
      `${host}${url}`,
      "headers",
      {
        authorization: `Bearer ${access_token}`,
        accept: "application/json",
        "content-type": "application/json",
      },
      "data",
      JSON.stringify(request.body)
    );

    ctx.body = result.data || {};

    return ctx.body;
  }

  async put() {
    const { ctx, config, logger } = this;
    const { originalUrl, session, curl, request } = ctx;
    const { hroProxy = {} } = config;
    const { host } = hroProxy;
    const { access_token } = session.user_info;
    const url = this.splitUrl(originalUrl);
    const options = this.getOptions(url, "PUT");

    this.addToken(options);
    addParams(options);

    const result = await curl(`${host}${url}`, {
      method: "PUT",
      dataType: "json",
      data: JSON.stringify(request.body),
      headers: {
        authorization: `Bearer ${access_token}`,
        accept: "application/json",
        "content-type": "application/json",
      },
    });

    logger.info(
      "put proxy url:",
      `${host}${url}`,
      "headers",
      {
        authorization: `Bearer ${access_token}`,
        accept: "application/json",
        "content-type": "application/json",
      },
      "data",
      JSON.stringify(request.body)
    );

    ctx.body = result.data || {};

    return ctx.body;
  }

  async head() {
    const { ctx, config, logger } = this;
    const { originalUrl, session, curl, request } = ctx;
    const { hroProxy = {} } = config;
    const { host } = hroProxy;
    const { access_token } = session.user_info;
    const url = this.splitUrl(originalUrl);
    const options = this.getOptions(url, "HEAD");

    this.addToken(options);
    addParams(options);

    const result = await curl(`${host}${url}`, {
      method: "HEAD",
      dataType: "json",
      data: JSON.stringify(request.body),
      headers: {
        authorization: `Bearer ${access_token}`,
        accept: "application/json",
        "content-type": "application/json",
      },
    });

    logger.info(
      "head proxy url:",
      `${host}${url}`,
      "headers",
      {
        authorization: `Bearer ${access_token}`,
        accept: "application/json",
        "content-type": "application/json",
      },
      "data",
      JSON.stringify(request.body)
    );

    ctx.body = result.data || {};

    return ctx.body;
  }

  async del() {
    const { ctx, config, logger } = this;
    const { originalUrl, session, curl } = ctx;
    const { hroProxy = {} } = config;
    const { host } = hroProxy;
    const { access_token } = session.user_info;
    const url = this.splitUrl(originalUrl);
    const options = this.getOptions(url, "DELETE");

    this.addToken(options);
    addParams(options);
    addContentLength(options);

    const result = await curl(`${host}${url}`, {
      method: "DELETE",
      dataType: "json",
      headers: {
        authorization: `Bearer ${access_token}`,
        accept: "application/json",
        "content-type": "application/json",
      },
    });

    logger.info("delete proxy url:", `${host}${url}`, "headers:", {
      authorization: `Bearer ${access_token}`,
      accept: "application/json",
      "content-type": "application/json",
    });

    ctx.body = result.data || {};

    return ctx.body;
  }
}

module.exports = ProxyController;