/*
 *  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 typeSerializers = require('./type-serializers');

/**
 * GraphSON2 writer.
 */
class GraphSON2Writer {

  /**
   * @param {Object} [options]
   * @param {Object} [options.serializers] An object used as an associative array with GraphSON 2 type name as keys and
   * serializer instances as values, ie: { 'g:Int64': longSerializer }.
   * @constructor
   */
  constructor(options) {
    this._options = options || {};
    // Create instance of the default serializers
    this._serializers = this.getDefaultSerializers().map(serializerConstructor => {
      const s = new serializerConstructor();
      s.writer = this;
      return s;
    });

    const customSerializers = this._options.serializers || {};

    Object.keys(customSerializers).forEach(key => {
      const s = customSerializers[key];
      if (!s.serialize) {
        return;
      }
      s.writer = this;
      // Insert custom serializers first
      this._serializers.unshift(s);
    });
  }

  /**
   * Gets the default serializers to be used.
   * @returns {Array}
   */
  getDefaultSerializers() {
    return graphSON2Serializers;
  }

  adaptObject(value) {
    let s;

    for (let i = 0; i < this._serializers.length; i++) {
      const currentSerializer = this._serializers[i];
      if (currentSerializer.canBeUsedFor && currentSerializer.canBeUsedFor(value)) {
        s = currentSerializer;
        break;
      }
    }

    if (s) {
      return s.serialize(value);
    }

    if (Array.isArray(value)) {
      // We need to handle arrays when there is no serializer
      // for older versions of GraphSON
      return value.map(item => this.adaptObject(item));
    }

    // Default (strings / objects / ...)
    return value;
  }

  /**
   * Returns the GraphSON representation of the provided object instance.
   * @param {Object} obj
   * @returns {String}
   */
  write(obj) {
    return JSON.stringify(this.adaptObject(obj));
  }
}

/**
 * GraphSON3 writer.
 */
class GraphSON3Writer extends GraphSON2Writer {
  getDefaultSerializers() {
    return graphSON3Serializers;
  }
}

/**
 * GraphSON2 reader.
 */
class GraphSON2Reader {
  /**
   * GraphSON Reader
   * @param {Object} [options]
   * @param {Object} [options.serializers] An object used as an associative array with GraphSON 2 type name as keys and
   * deserializer instances as values, ie: { 'g:Int64': longSerializer }.
   * @constructor
   */
  constructor(options) {
    this._options = options || {};
    this._deserializers = {};

    const defaultDeserializers = this.getDefaultDeserializers();
    Object.keys(defaultDeserializers).forEach(typeName => {
      const serializerConstructor = defaultDeserializers[typeName];
      const s = new serializerConstructor();
      s.reader = this;
      this._deserializers[typeName] = s;
    });

    if (this._options.serializers) {
      const customSerializers = this._options.serializers || {};
      Object.keys(customSerializers).forEach(key => {
        const s = customSerializers[key];
        if (!s.deserialize) {
          return;
        }
        s.reader = this;
        this._deserializers[key] = s;
      });
    }
  }

  /**
   * Gets the default deserializers as an associative array.
   * @returns {Object}
   */
  getDefaultDeserializers() {
    return graphSON2Deserializers;
  }

  read(obj) {
    if (obj === undefined) {
      return undefined;
    }
    if (obj === null) {
      return null;
    }
    if (Array.isArray(obj)) {
      return obj.map(item => this.read(item));
    }
    const type = obj[typeSerializers.typeKey];
    if (type) {
      const d = this._deserializers[type];
      if (d) {
        // Use type serializer
        return d.deserialize(obj);
      }
      return obj[typeSerializers.valueKey];
    }
    if (obj && typeof obj === 'object' && obj.constructor === Object) {
      return this._deserializeObject(obj);
    }
    // Default (for boolean, number and other scalars)
    return obj;
  }

  _deserializeObject(obj) {
    const keys = Object.keys(obj);
    const result = {};
    for (let i = 0; i < keys.length; i++) {
      result[keys[i]] = this.read(obj[keys[i]]);
    }
    return result;
  }
}

/**
 * GraphSON3 reader.
 */
class GraphSON3Reader extends GraphSON2Reader {
  getDefaultDeserializers() {
    return graphSON3Deserializers;
  }
}

const graphSON2Deserializers = {
  'g:Traverser': typeSerializers.TraverserSerializer,
  'g:TraversalStrategy': typeSerializers.TraversalStrategySerializer,
  'g:Int32':  typeSerializers.NumberSerializer,
  'g:Int64':  typeSerializers.NumberSerializer,
  'g:Float':  typeSerializers.NumberSerializer,
  'g:Double': typeSerializers.NumberSerializer,
  'g:Date': typeSerializers.DateSerializer,
  'g:Vertex': typeSerializers.VertexSerializer,
  'g:Edge': typeSerializers.EdgeSerializer,
  'g:VertexProperty': typeSerializers.VertexPropertySerializer,
  'g:Property': typeSerializers.PropertySerializer,
  'g:Path': typeSerializers.Path3Serializer,
  'g:T': typeSerializers.TSerializer
};

const graphSON3Deserializers = Object.assign({}, graphSON2Deserializers, {
  'g:List': typeSerializers.ListSerializer,
  'g:Set': typeSerializers.SetSerializer,
  'g:Map': typeSerializers.MapSerializer
});

const graphSON2Serializers = [
  typeSerializers.NumberSerializer,
  typeSerializers.DateSerializer,
  typeSerializers.BytecodeSerializer,
  typeSerializers.TraverserSerializer,
  typeSerializers.TraversalStrategySerializer,
  typeSerializers.PSerializer,
  typeSerializers.LambdaSerializer,
  typeSerializers.EnumSerializer,
  typeSerializers.VertexSerializer,
  typeSerializers.EdgeSerializer,
  typeSerializers.LongSerializer
];

const graphSON3Serializers = graphSON2Serializers.concat([
  typeSerializers.ListSerializer,
  typeSerializers.SetSerializer,
  typeSerializers.MapSerializer
]);

module.exports = {
  GraphSON3Writer,
  GraphSON3Reader,
  GraphSON2Writer,
  GraphSON2Reader,
  GraphSONWriter: GraphSON3Writer,
  GraphSONReader: GraphSON3Reader
};