import { DEFAULT_TAP, DEFAULT_SWIPE } from '../../components/Inspector/shared';

export default class Framework {

  constructor (host, port, path, https, caps, filePath, cookie, requestVars) {
    this.host = host || 'localhost';
    this.port = port || 4723;
    this.path = path || '/wd/hub';
    this.caps = caps || {};
    this.filePath = filePath;
    this.cookie = cookie || 'experimentation_subject_id=imuzndu1mdjkltuwmdctndk2ys1hmtljlti1owrlnjc4yzfmosi%3d--fb98d346787f918849a9c9f856a783933b9fbe94; sensorsdata2015jssdkcross=%7b%22distinct_id%22%3a%22cwmsvtiu%22%2c%22%24device_id%22%3a%221818b7939df5b9-0e4072c3066eed-1d525635-1930176-1818b7939e01c4e%22%2c%22props%22%3a%7b%22%24latest_referrer%22%3a%22%22%2c%22%24latest_traffic_source_type%22%3a%22%e7%9b%b4%e6%8e%a5%e6%b5%81%e9%87%8f%22%2c%22%24latest_search_keyword%22%3a%22%e6%9c%aa%e5%8f%96%e5%88%b0%e5%80%bc_%e7%9b%b4%e6%8e%a5%e6%89%93%e5%bc%80%22%7d%2c%22first_id%22%3a%221818b7939df5b9-0e4072c3066eed-1d525635-1930176-1818b7939e01c4e%22%2c%22identities%22%3a%22eyikawrlbnrpdhlfy29va2llx2lkijoimtgzmgi2mmnlmwyymdqtmdc0zwuzyjiyztdlogy4ltfinti1njm1lte5mzaxnzytmtgzmgi2mmnlmjaxyzg3iiwijglkzw50axr5x2xvz2lux2lkijoiq3dnc3z0avuifq%3d%3d%22%2c%22history_login_id%22%3a%7b%22name%22%3a%22%24identity_login_id%22%2c%22value%22%3a%22cwmsvtiu%22%7d%7d; remember_token=6406f1f672e4efcd4d47d36a|2715bd37fbd1a85bf9604019b6c5e81b0a65ef56f0f58f90ddc55b6b2e7b82e73ec866863cf358339e80d0b60d7f21ddcce9ee80d47879e9a045ed8bd13beb7f; session=.ejwdyzsoajemang7pkawhcdjuazyv9duqow4o4hypdfv9jrzud2ixzswsghjpoqsdw6e0uxbpd3qyppers_jlb_6c8wxmxn73ds5azkvdz6oi5eyvuipjy30nhlb-hswqo5ftrhvezurosuog16mmx227tadoyvloyapdakbxwbzap5wxvju7fmfh0020g.zcer_g.cq9eqooxjtrerz589dhvixjvkqe; auto-ftest=eyjhbgcioijiuzuxmiisimlhdci6mty3otg5ntu1mcwizxhwijoxnjc5otaynzuwfq.eyjlbwfpbci6innozw5szwlazm9yew91ntyuy29tiiwicm9szxmiolsichjvamvjdcisinvzzxiilcjhzg1pbijdlcjuyw1lijoi5rki6zu3iiwibw9iawxlijoimtm2mdawmdawmdaifq.s7ghd-yfdtpkva1qog8f2x9-qw8j9thdpglaekvl-oz3o98gkgwpve1g1u8pig0bsihghirh_9p_4zzikizdoq; auto-ftest=eyjhbgcioijiuzuxmiisimlhdci6mty3otg5ntu1mcwizxhwijoxnjc5otaynzuwfq.eyjlbwfpbci6innozw5szwlazm9yew91ntyuy29tiiwicm9szxmiolsichjvamvjdcisinvzzxiilcjhzg1pbijdlcjuyw1lijoi5rki6zu3iiwibw9iawxlijoimtm2mdawmdawmdaifq.s7ghd-yfdtpkva1qog8f2x9-qw8j9thdpglaekvl-oz3o98gkgwpve1g1u8pig0bsihghirh_9p_4zzikizdoq; auth-token=eyjhbgcioijiuzuxmiisimlhdci6mty3otg5ntu1mcwizxhwijoxnjc5otaynzuwfq.eyjlbwfpbci6innozw5szwlazm9yew91ntyuy29tiiwicm9szxmiolsichjvamvjdcisinvzzxiilcjhzg1pbijdlcjuyw1lijoi5rki6zu3iiwibw9iawxlijoimtm2mdawmdawmdaifq.s7ghd-yfdtpkva1qog8f2x9-qw8j9thdpglaekvl-oz3o98gkgwpve1g1u8pig0bsihghirh_9p_4zzikizdoq';
    this.https = !!https;
    this.scheme = https ? 'https' : 'http';
    // this.actions = [];
    this.localVarCount = 0;
    this.assertVarCount = 0;
    this.localVarCache = {};
    this.lastAssignedVar = null;
    this.requestVars = requestVars;
    console.log('caps ========' + caps);
  }

  getTapCoordinatesFromPointerActions (pointerActions) {
    const pointerMoveAction = pointerActions[DEFAULT_TAP.POINTER_NAME][0];
    return {x: pointerMoveAction.x, y: pointerMoveAction.y};
  }

  getSwipeCoordinatesFromPointerActions (pointerActions) {
    const pointerMoveActionStart = pointerActions[DEFAULT_SWIPE.POINTER_NAME][0];
    const pointerMoveActionEnd = pointerActions[DEFAULT_SWIPE.POINTER_NAME][2];

    return {
      x1: pointerMoveActionStart.x,
      y1: pointerMoveActionStart.y,
      x2: pointerMoveActionEnd.x,
      y2: pointerMoveActionEnd.y
    };
  }

  get serverUrl () {
    return `${this.scheme}://${this.host}:${this.port}${this.path}`;
  }

  get name () {
    throw new Error('Must implement name getter');
  }

  get language () {
    throw new Error('Must implement language getter');
  }

  addAction (action, params) {
    this.actions.push({action, params});
  }

  wrapWithBoilerplate () {
    throw new Error('Must implement wrapWithBoilerplate');
  }

  indent (str, spaces) {
    let lines = str.split('\n');
    let spaceStr = '';
    for (let i = 0; i < spaces; i++) {
      spaceStr += ' ';
    }
    return lines
      .filter((l) => !!l.trim())
      .map((l) => `${spaceStr}${l}`)
      .join('\n');
  }

  getActionCodeString (actions) {
    let str = '//\n';
    for (let {action, params} of actions) {
      const genCodeFn = `codeFor_${action}`;
      if (!this[genCodeFn]) {
        throw new Error(`Need to implement '${genCodeFn}()': ${this[genCodeFn]}`);
      }
      let code = this[genCodeFn](...params);
      if (code) {
        str += `${code}\n`;
      }
    }
    if (actions.map((element) => element.action).indexOf('insertIt') === -1) {
      str += 'await driver.pause(2000);\n';
    }
    return str;
  }
  getCodeString (recordContent, includeBoilerplate = false) {
    if (includeBoilerplate) {
      return this.wrapWithBoilerplate(recordContent);
    }
    return recordContent;
  }
  // getCodeString (includeBoilerplate = false) {
  //   let str = '';
  //   for (let {action, params} of this.actions) {
  //     const genCodeFn = `codeFor_${action}`;
  //     if (!this[genCodeFn]) {
  //       throw new Error(`Need to implement '${genCodeFn}()': ${this[genCodeFn]}`);
  //     }
  //     let code = this[genCodeFn](...params);
  //     if (code) {
  //       str += `${code}\n`;
  //     }
  //   }
  //   if (includeBoilerplate) {
  //     return this.wrapWithBoilerplate(str);
  //   }
  //   return str;
  // }

  getNewLocalVar () {
    this.localVarCount++;
    return `el${this.localVarCount}`;
  }

  getVarForFind (strategy, locator) {
    const key = `${strategy}-${locator}`;
    let wasNew = false;
    if (!this.localVarCache[key]) {
      this.localVarCache[key] = this.getNewLocalVar();
      wasNew = true;
    }
    this.lastAssignedVar = this.localVarCache[key];
    return [this.localVarCache[key], wasNew];
  }

  getVarName (varName, varIndex) {
    if (varIndex || varIndex === 0) {
      return `${varName}[${varIndex}]`;
    }
    return varName;
  }

  codeFor_findAndAssign () {
    throw new Error('Need to implement codeFor_findAndAssign');
  }

  codeFor_findElement (strategy, locator) {
    let [localVar, wasNew] = this.getVarForFind(strategy, locator);
    if (!wasNew) {
      // if we've already found this element, don't print out
      // finding it again
      return '';
    }

    return this.codeFor_findAndAssign(strategy, locator, localVar);

  }

  codeFor_tap () {
    throw new Error('Need to implement codeFor_tap');
  }

  codeFor_swipe () {
    throw new Error('Need to implement codeFor_tap');
  }
}
