"use strict";

var _express = _interopRequireDefault(require("express"));

var _gitlab = require("gitlab");

var _esprima = _interopRequireDefault(require("esprima"));

var _utils = require("../utils");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

let options = (0, _utils.getOptions)();
let {
  impact: {
    server
  }
} = options;
let serverUrl = (0, _utils.getServerURL)(server, 'htt' + 'p');
let {
  port
} = server;
const services = new _gitlab.ProjectsBundle({
  url: 'https://git.csez.zohocorpin.com',
  token: 'n6aqQz3RfzqRGPyMTPy8'
});
let app = (0, _express.default)();
app.use(_express.default.json());
app.use(_express.default.urlencoded({
  extended: true
}));

function traverseJSON(parsed, file) {
  let parsedObj = {};
  parsed.forEach(Block => {
    if (Block.type === 'FunctionDeclaration' || Block.type === 'ExportDefaultDeclaration' || Block.type === 'ExportNamedDeclaration') {
      let ParsedTemp;

      if (Block.type === 'FunctionDeclaration') {
        ParsedTemp = Block;
      } else {
        ParsedTemp = Block.declaration;
      }

      if (ParsedTemp) {
        if (ParsedTemp.id) {
          let funcname = ParsedTemp.id.name;

          if (funcname !== 'mapStateToProps') {
            if (!funcname.includes('_')) {
              if (!Object.prototype.hasOwnProperty.call(parsedObj, 'file')) {
                parsedObj[file] = {};
              }

              let tempArray = [];

              for (let j = ParsedTemp.loc.start.line; j < ParsedTemp.loc.end.line; j++) {
                tempArray.push(j);
              }

              parsedObj[file][funcname] = tempArray;
            }
          }
        }
      }
    }
  });
  return parsedObj;
}

function getDetails(url, callback) {
  let changeObj = {};
  let compObj = {};
  (0, _utils.request)({
    url
  }).then(res => {
    let body = JSON.parse(res.body);

    if (body.includes('Source_Changeset')) {
      let branch, changeSet;
      body = body.split('\n');
      body.forEach(content => {
        if (content.includes('Source_Changeset')) {
          let [, __changeSet] = content.split('=');
          changeSet = __changeSet;
        }

        if (content.includes('SourceCoLabel')) {
          let [__branch] = content.split('=');
          branch = __branch;
        }
      });
      services.Commits.diff(1143, changeSet //'587efd32ce14620750a38ab74bc744fc52f2943a '
      ).then(result => {
        let promises = [];

        if (result) {
          result.forEach(change => {
            let p = new Promise(resolve => {
              let filename = change.new_path;
              changeObj[filename] = [];
              compObj[filename] = [];
              let diffList = change.diff.split('\n');
              let tempObj = {};
              diffList.forEach(diff => {
                if (diff.indexOf('data-id') >= 0) {
                  if (diff.indexOf('//') >= 0) {
                    if (diff.substr(diff.indexOf('//') + 1).includes('data-id')) {
                      //eslint-disable-next-line
                      tempObj.defaultId = diff.match(/(data-id=.*)/g)[0].match(/["']([^"']+?)['"]/g)[0];
                      tempObj.changedId = null;
                    }
                  }

                  if (!diff.indexOf('-')) {
                    //eslint-disable-next-line
                    tempObj.defaultId = diff.match(/(data-id=.*)/g)[0].match(/["']([^"']+?)['"]/g)[0];
                    let tempIndex = diffList.indexOf(diff);

                    if (diffList[tempIndex + 1].indexOf('data-id') === -1) {
                      tempObj.changedId = null;
                    }
                  }

                  if (!diff.indexOf('+')) {
                    //eslint-disable-next-line
                    tempObj.changedId = diff.match(/(data-id=.*)/g)[0].match(/["']([^"']+?)['"]/g)[0];
                    let tempIndex = diffList.indexOf(diff);

                    if (diffList[tempIndex - 1].indexOf('data-id') === -1) {
                      tempObj.defaultId = null;
                    }
                  }

                  if (Object.prototype.hasOwnProperty.call(tempObj, 'defaultId') && Object.prototype.hasOwnProperty.call(tempObj, 'changedId')) {
                    if (tempObj.defaultId !== tempObj.changedId) {
                      compObj[filename].push(tempObj);
                      tempObj = {};
                    }
                  }
                }

                if (diff.startsWith('@')) {
                  let [, content] = diff.split('@@');
                  let tempList = content.split(' ');
                  let startingLine = parseInt(tempList[1].split(',')[0]) * -1 + 3;
                  let furtherLines = parseInt(tempList[2].split(',')[0]) + 3;

                  if (parseInt(tempList[1].split(',')[1]) > 6) {
                    changeObj[filename].push(startingLine);
                  }

                  if (parseInt(tempList[2].split(',')[1]) > 6) {
                    let endValue = parseInt(tempList[2].split(',')[1]) - 6;

                    for (let i = furtherLines; i < furtherLines + endValue; i++) {
                      changeObj[filename].push(i);
                    }
                  }
                }
              });

              if (!filename.includes('.spec.js') && !filename.includes('.docs.js') && !filename.includes('.css') && filename.includes('.js')) {
                try {
                  services.RepositoryFiles.show(1143, filename, branch).then(res => {
                    let code = Buffer.from(res.content, 'base64').toString('ascii');

                    let parsed = _esprima.default.parseModule(code, {
                      jsx: true,
                      loc: true
                    });

                    let methodDetail = traverseJSON(parsed.body, filename);

                    if (Object.keys(methodDetail).length) {
                      resolve(methodDetail);
                    } else {
                      resolve(false);
                    }
                  });
                } catch (err) {
                  (0, _utils.log)(err);
                }
              } else {
                resolve(false);
              }
            });
            promises.push(p);
          });
          Promise.all(promises).then(resPromise => {
            callback(changeObj, Object.assign({}, ...resPromise), compObj);
          });
        }
      });
    }
  }).catch(err => err);
}

app.post('/impact/build', (req, res) => {
  req.setTimeout(0);
  let subUrl = '/logs/reactbuildinfo.txt';
  let {
    body: build
  } = req;
  let url = build.buildUrl.substr(0, build.buildUrl.lastIndexOf('/'));
  url = url + subUrl;
  getDetails(url, (body, esprimaObj, componentObj, err) => {
    if (err) {
      return err;
    }

    let responseObj = {};
    Object.keys(esprimaObj).forEach(file => {
      responseObj[file] = [];
      body[file].forEach(changedLine => {
        Object.keys(esprimaObj[file]).forEach(method => {
          if (esprimaObj[file][method].includes(changedLine)) {
            if (!responseObj[file].includes(method)) {
              responseObj[file].push(method);
            }
          }
        });
      });

      if (!responseObj[file].length) {
        delete responseObj[file];
      }
    });
    let resObj = {
      chnagedMethods: responseObj,
      changedLocators: componentObj
    };
    res.send(resObj);
    res.end();
  });
});
app.listen(port, err => {
  if (err) {
    throw err;
  }

  (0, _utils.log)(`Listening at ${serverUrl}/impact/build/`);
  (0, _utils.log)('payload like => {buildUrl:test_build_url}');
});