/*
 *  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 { Traversal } = require('./traversal');
const remote = require('../driver/remote-connection');
const utils = require('../utils');
const Bytecode = require('./bytecode');
const { TraversalStrategies, VertexProgramStrategy } = require('./traversal-strategy');


/**
 * Represents the primary DSL of the Gremlin traversal machine.
 */
class GraphTraversalSource {

  /**
   * Creates a new instance of {@link GraphTraversalSource}.
   * @param {Graph} graph
   * @param {TraversalStrategies} traversalStrategies
   * @param {Bytecode} [bytecode]
   * @param {Function} [graphTraversalSourceClass] Optional {@link GraphTraversalSource} constructor.
   * @param {Function} [graphTraversalClass] Optional {@link GraphTraversal} constructor.
   */
  constructor(graph, traversalStrategies, bytecode, graphTraversalSourceClass, graphTraversalClass) {
    this.graph = graph;
    this.traversalStrategies = traversalStrategies;
    this.bytecode = bytecode || new Bytecode();
    this.graphTraversalSourceClass = graphTraversalSourceClass || GraphTraversalSource;
    this.graphTraversalClass = graphTraversalClass || GraphTraversal;
  }

  /**
   * @param remoteConnection
   * @returns {GraphTraversalSource}
   */
  withRemote(remoteConnection) {
    const traversalStrategy = new TraversalStrategies(this.traversalStrategies);
    traversalStrategy.addStrategy(new remote.RemoteStrategy(remoteConnection));
    return new this.graphTraversalSourceClass(this.graph, traversalStrategy, new Bytecode(this.bytecode), this.graphTraversalSourceClass, this.graphTraversalClass);
  }

  /**
   * @param graphComputer
   * @param workers
   * @param result
   * @param persist
   * @param vertices
   * @param edges
   * @param configuration
   * @returns {GraphTraversalSource}
   */
  withComputer(graphComputer, workers, result, persist, vertices, edges, configuration) {
    return this.withStrategies(new VertexProgramStrategy(graphComputer, workers, result, persist, vertices, edges, configuration));
  }

  /**
   * Returns the string representation of the GraphTraversalSource.
   * @returns {string}
   */
  toString() {
    return 'graphtraversalsource[' + this.graph.toString() + ']';
  }
  <% sourceStepMethods.each{ method -> %>
  /**
   * Graph Traversal Source <%= method %> method.
   * @param {...Object} args
   * @returns {GraphTraversalSource}
   */
  <%= toJs.call(method) %>(...args) {
    const b = new Bytecode(this.bytecode).addSource('<%= method %>', args);
    return new this.graphTraversalSourceClass(this.graph, new TraversalStrategies(this.traversalStrategies), b, this.graphTraversalSourceClass, this.graphTraversalClass);
  }
  <%
  }
  sourceSpawnMethods.each{ method -> %>
  /**
   * <%= method %> GraphTraversalSource step method.
   * @param {...Object} args
   * @returns {GraphTraversal}
   */
  <%= toJs.call(method) %>(...args) {
    const b = new Bytecode(this.bytecode).addStep('<%= method %>', args);
    return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), b);
  }
  <% } %>
}

/**
 * Represents a graph traversal.
 */
class GraphTraversal extends Traversal {
  constructor(graph, traversalStrategies, bytecode) {
    super(graph, traversalStrategies, bytecode);
  }

  /**
   * Copy a traversal so as to reset and re-use it.
   */
  clone() {
    return new GraphTraversal(this.graph, this.traversalStrategies, this.getBytecode());
  }

  <% graphStepMethods.each{ method -> %>
  /**
   * Graph traversal <%= method %> method.
   * @param {...Object} args
   * @returns {GraphTraversal}
   */
  <%= toJs.call(method) %>(...args) {
    this.bytecode.addStep('<%= method %>', args);
    return this;
  }
  <% } %>
}

function callOnEmptyTraversal(fnName, args) {
  const g = new GraphTraversal(null, null, new Bytecode());
  return g[fnName].apply(g, args);
}

/**
 * Contains the static method definitions
 * @type {Object}
 */
const statics = {<% anonStepMethods.eachWithIndex { method, i -> %>
  <%= toJs.call(method) %>: (...args) => callOnEmptyTraversal('<%= toJs.call(method) %>', args)<%= i < anonStepMethods.size() - 1 ? "," : ""%><% } %>
};

module.exports = {
  GraphTraversal,
  GraphTraversalSource,
  statics
};