/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */

/**
 * @author Jorge Bay Gondra
 */

'use strict';

const itemDone = Object.freeze({ value: null, done: true });
const asyncIteratorSymbol = Symbol.asyncIterator || Symbol('@@asyncIterator');

class Traversal {
  constructor(graph, traversalStrategies, bytecode) {
    this.graph = graph;
    this.traversalStrategies = traversalStrategies;
    this.bytecode = bytecode;
    /** @type {Array<Traverser>} */
    this.traversers = null;
    this.sideEffects = null;
    this._traversalStrategiesPromise = null;
    this._traversersIteratorIndex = 0;
  }

  /**
   * Async iterable method implementation.
   */
  [asyncIteratorSymbol]() {
    return this;
  }

  /** @returns {Bytecode} */
  getBytecode() {
    return this.bytecode;
  }

  /**
   * Returns an Array containing the traverser objects.
   * @returns {Promise.<Array>}
   */
  toList() {
    return this._applyStrategies().then(() => {
      const result = [];
      let it;
      while ((it = this._getNext()) && !it.done) {
        result.push(it.value);
      }
      return result;
    });
  }

  /**
   * Determines if there are any more items to iterate from the traversal.
   * @returns {Promise.<boolean>}
   */
  hasNext() {
    return this._applyStrategies().then(
      () =>
        this.traversers &&
        this.traversers.length > 0 &&
        this._traversersIteratorIndex < this.traversers.length &&
        this.traversers[this._traversersIteratorIndex].bulk > 0,
    );
  }

  /**
   * Iterates all Traverser instances in the traversal.
   * @returns {Promise}
   */
  iterate() {
    this.bytecode.addStep('none');
    return this._applyStrategies().then(() => {
      let it;
      while ((it = this._getNext()) && !it.done) {
        //
      }
    });
  }

  /**
   * Async iterator method implementation.
   * Returns a promise containing an iterator item.
   * @returns {Promise.<{value, done}>}
   */
  next() {
    return this._applyStrategies().then(() => this._getNext());
  }

  /**
   * Synchronous iterator of traversers including
   * @private
   */
  _getNext() {
    while (this.traversers && this._traversersIteratorIndex < this.traversers.length) {
      const traverser = this.traversers[this._traversersIteratorIndex];
      if (traverser.bulk > 0) {
        traverser.bulk--;
        return { value: traverser.object, done: false };
      }
      this._traversersIteratorIndex++;
    }
    return itemDone;
  }

  _applyStrategies() {
    if (this._traversalStrategiesPromise) {
      // Apply strategies only once
      return this._traversalStrategiesPromise;
    }
    return (this._traversalStrategiesPromise = this.traversalStrategies.applyStrategies(this));
  }

  /**
   * Returns step instructions during JSON serialization
   * @returns {Array}
   */
  toJSON() {
    return this.bytecode.stepInstructions;
  }

  /**
   * Returns the Bytecode JSON representation of the traversal
   * @returns {String}
   */
  toString() {
    return this.bytecode.toString();
  }
}

class IO {
  static get graphml() {
    return 'graphml';
  }

  static get graphson() {
    return 'graphson';
  }

  static get gryo() {
    return 'gryo';
  }

  static get reader() {
    return '~tinkerpop.io.reader';
  }

  static get registry() {
    return '~tinkerpop.io.registry';
  }

  static get writer() {
    return '~tinkerpop.io.writer';
  }
}

// eslint-disable-next-line no-unused-vars
class ConnectedComponent {
  static get component() {
    return 'gremlin.connectedComponentVertexProgram.component';
  }

  static get edges() {
    return '~tinkerpop.connectedComponent.edges';
  }

  static get propertyName() {
    return '~tinkerpop.connectedComponent.propertyName';
  }
}

// eslint-disable-next-line no-unused-vars
class ShortestPath {
  static get distance() {
    return '~tinkerpop.shortestPath.distance';
  }

  static get edges() {
    return '~tinkerpop.shortestPath.edges';
  }

  static get includeEdges() {
    return '~tinkerpop.shortestPath.includeEdges';
  }

  static get maxDistance() {
    return '~tinkerpop.shortestPath.maxDistance';
  }

  static get target() {
    return '~tinkerpop.shortestPath.target';
  }
}

// eslint-disable-next-line no-unused-vars
class PageRank {
  static get edges() {
    return '~tinkerpop.pageRank.edges';
  }

  static get propertyName() {
    return '~tinkerpop.pageRank.propertyName';
  }

  static get times() {
    return '~tinkerpop.pageRank.times';
  }
}

// eslint-disable-next-line no-unused-vars
class PeerPressure {
  static get edges() {
    return '~tinkerpop.peerPressure.edges';
  }

  static get propertyName() {
    return '~tinkerpop.peerPressure.propertyName';
  }

  static get times() {
    return '~tinkerpop.peerPressure.times';
  }
}

class P {
  /**
   * Represents an operation.
   * @constructor
   */
  constructor(operator, value, other) {
    this.operator = operator;
    this.value = value;
    this.other = other;
  }

  /**
   * Returns the string representation of the instance.
   * @returns {string}
   */
  toString() {
    function formatValue(value) {
      if (Array.isArray(value)) {
        const acc = [];
        for (const item of value) {
          acc.push(formatValue(item));
        }
        return acc;
      }
      if (value && typeof value === 'string') {
        return `'${value}'`;
      }
      return value;
    }

    if (this.other === undefined || this.other === null) {
      return this.operator + '(' + formatValue(this.value) + ')';
    }
    return this.operator + '(' + formatValue(this.value) + ', ' + formatValue(this.other) + ')';
  }

  and(arg) {
    return new P('and', this, arg);
  }

  or(arg) {
    return new P('or', this, arg);
  }

  static within(...args) {
    if (args.length === 1 && Array.isArray(args[0])) {
      return new P('within', args[0], null);
    }
    return new P('within', args, null);
  }

  static without(...args) {
    if (args.length === 1 && Array.isArray(args[0])) {
      return new P('without', args[0], null);
    }
    return new P('without', args, null);
  }

  /** @param {...Object} args */
  static between(...args) {
    return createP('between', args);
  }

  /** @param {...Object} args */
  static eq(...args) {
    return createP('eq', args);
  }

  /** @param {...Object} args */
  static gt(...args) {
    return createP('gt', args);
  }

  /** @param {...Object} args */
  static gte(...args) {
    return createP('gte', args);
  }

  /** @param {...Object} args */
  static inside(...args) {
    return createP('inside', args);
  }

  /** @param {...Object} args */
  static lt(...args) {
    return createP('lt', args);
  }

  /** @param {...Object} args */
  static lte(...args) {
    return createP('lte', args);
  }

  /** @param {...Object} args */
  static neq(...args) {
    return createP('neq', args);
  }

  /** @param {...Object} args */
  static not(...args) {
    return createP('not', args);
  }

  /** @param {...Object} args */
  static outside(...args) {
    return createP('outside', args);
  }

  /** @param {...Object} args */
  static test(...args) {
    return createP('test', args);
  }
}

function createP(operator, args) {
  args.unshift(null, operator);
  return new (Function.prototype.bind.apply(P, args))();
}

class TextP {
  /**
   * Represents an operation.
   * @constructor
   */
  constructor(operator, value, other) {
    this.operator = operator;
    this.value = value;
    this.other = other;
  }

  /**
   * Returns the string representation of the instance.
   * @returns {string}
   */
  toString() {
    function formatValue(value) {
      if (value && typeof value === 'string') {
        return `'${value}'`;
      }
      return value;
    }

    if (this.other === undefined) {
      return this.operator + '(' + formatValue(this.value) + ')';
    }
    return this.operator + '(' + formatValue(this.value) + ', ' + formatValue(this.other) + ')';
  }

  and(arg) {
    return new P('and', this, arg);
  }

  or(arg) {
    return new P('or', this, arg);
  }

  /** @param {...Object} args */
  static containing(...args) {
    return createTextP('containing', args);
  }

  /** @param {...Object} args */
  static endingWith(...args) {
    return createTextP('endingWith', args);
  }

  /** @param {...Object} args */
  static notContaining(...args) {
    return createTextP('notContaining', args);
  }

  /** @param {...Object} args */
  static notEndingWith(...args) {
    return createTextP('notEndingWith', args);
  }

  /** @param {...Object} args */
  static notStartingWith(...args) {
    return createTextP('notStartingWith', args);
  }

  /** @param {...Object} args */
  static startingWith(...args) {
    return createTextP('startingWith', args);
  }

  /** @param {...Object} args */
  static regex(...args) {
    return createTextP('regex', args);
  }

  /** @param {...Object} args */
  static notRegex(...args) {
    return createTextP('notRegex', args);
  }
}

function createTextP(operator, args) {
  args.unshift(null, operator);
  return new (Function.prototype.bind.apply(TextP, args))();
}

class Traverser {
  constructor(object, bulk) {
    this.object = object;
    this.bulk = bulk || 1;
  }
}

class TraversalSideEffects {}

const withOptions = {
  tokens: '~tinkerpop.valueMap.tokens',
  none: 0,
  ids: 1,
  labels: 2,
  keys: 4,
  values: 8,
  all: 15,
  indexer: '~tinkerpop.index.indexer',
  list: 0,
  map: 1,
};

function toEnum(typeName, keys) {
  const result = {};
  keys.split(' ').forEach((k) => {
    let jsKey = k;
    if (jsKey === jsKey.toUpperCase()) {
      jsKey = jsKey.toLowerCase();
    }
    result[jsKey] = new EnumValue(typeName, k);
  });
  return result;
}

const directionAlias = {
  from_: 'out',
  to: 'in',
};

// for direction enums, maps the same EnumValue object to the enum aliases after creating them
function toDirectionEnum(typeName, keys) {
  const result = toEnum(typeName, keys);
  Object.keys(directionAlias).forEach((k) => {
    result[k] = result[directionAlias[k]];
  });
  return result;
}

class EnumValue {
  constructor(typeName, elementName) {
    this.typeName = typeName;
    this.elementName = elementName;
  }

  toString() {
    return this.elementName;
  }
}

module.exports = {
  EnumValue,
  P,
  TextP,
  withOptions,
  IO,
  Traversal,
  TraversalSideEffects,
  Traverser,
  barrier: toEnum('Barrier', 'normSack'),
  cardinality: toEnum('Cardinality', 'list set single'),
  column: toEnum('Column', 'keys values'),
  direction: toDirectionEnum('Direction', 'BOTH IN OUT from_ to'),
  dt: toEnum('DT', 'second minute hour day'),
  graphSONVersion: toEnum('GraphSONVersion', 'V1_0 V2_0 V3_0'),
  gryoVersion: toEnum('GryoVersion', 'V1_0 V3_0'),
  merge: toEnum('Merge', 'onCreate onMatch outV inV'),
  operator: toEnum('Operator', 'addAll and assign div max min minus mult or sum sumLong'),
  order: toEnum('Order', 'asc desc shuffle'),
  pick: toEnum('Pick', 'any none'),
  pop: toEnum('Pop', 'all first last mixed'),
  scope: toEnum('Scope', 'global local'),
  t: toEnum('T', 'id key label value'),
};
