'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 } = this;
    const { restful = {} } = config;
    const { version, host, port } = restful;
    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': {
        "Accept": "application/json",
        "Content-Type": "application/json",
        'User-Agent': 'Request for Express'
      }
    };
  }

  async get() {
    const { ctx, config, logger } = this;
    const { originalUrl, session, curl } = ctx;
    const { restful = {} } = config;
    const { host } = restful;
    const { access_token } = session.user_info;
    const url = splitUrl(originalUrl);
    const options = getOptions(url, 'GET');

    addToken(options);

    const result = await curl(
      `${host}${url}`,
      {
        method: 'GET',
        dataType: 'json',
        headers: {
          'authorization': `Bearer ${access_token}`,
          'accept': 'application/json',
          'content-type': 'application/json'
        },
        timeout: [5000, 60000]
      }
    );

    logger.info(
      "get originalUrl:",
      `${splitUrl(originalUrl)}`,
      "get host:",
      `${host}`,
      "get url:",
      `${url}`,
      "result:",
      result
    );

    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 = splitUrl(originalUrl);
    const options = getOptions(url, 'POST');

    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 = splitUrl(originalUrl);
    const options = getOptions(url, 'PUT');

    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 = splitUrl(originalUrl);
    const options = getOptions(url, 'HEAD');

    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 = splitUrl(originalUrl);
    const options = getOptions(url, 'DELETE');

    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;