// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/**
 * @fileoverview Tests for TypeEncoder and TypeDecoder.
 */

var test = require('prova');

var stringify = require('./../../src/vdl/stringify.js');
var types = require('./../../src/vdl/types.js');
var kind = require('./../../src/vdl/kind.js');
var Promise = require('./../../src/lib/promise');

var TypeEncoder = require('./../../src/vom/type-encoder.js');
var TypeDecoder = require('./../../src/vom/type-decoder.js');

var ByteArrayMessageWriter = require(
    './../../src/vom/byte-array-message-writer.js');
var RawVomReader = require('./../../src/vom/raw-vom-reader.js');

/**
 * Type message reader reads type messages from the provided data.
 * @param {Uint8Array} bytes The input data.
 * @constructor
 */
function TypeMessageReader(bytes) {
  var header = bytes[0];
  this.rawReader = new RawVomReader(bytes);
  // consume the header byte.
  this.rawReader._readRawBytes(1);
  if (header !== 0x80) {
    throw new Error('Improperly formatted bytes. Must start with 0x80');
  }
}

/**
 * Read the next type message.
 */
TypeMessageReader.prototype.nextMessage = function(typeDecoder) {
  var reader = this;
  return this.rawReader.readInt().then(function(typeId) {
    if (typeId >= 0) {
      throw new Error('Value messages not implemented.');
    }
    return reader.rawReader.readUint().then(function(len) {
      return reader.rawReader._readRawBytes(len);
    }).then(function(bytes) {
      return {
        typeId: -typeId,
        messageBytes: bytes,
      };
    });
  }, function(err) {
    return null;
  });
};

test('type encoding encode and decode (optional fields filled)', function(t) {
  var tests = require('../vdl/type-test-cases.js');
  var promises = [];
  for (var i = 0; i < tests.length; i++) {
    promises.push(encodeDecodeType(t, tests[i].type));
  }
  Promise.all(promises).then(function() {
    t.end();
  }, t.end);
});

test('type encoding encode and decode (optional fields omitted)',
  function(t) {
  var tests = [
    {
      test: {
        kind: kind.OPTIONAL,
        elem: types.UINT64
      },
      expected: {
        name: '',
        kind: kind.OPTIONAL,
        elem: types.UINT64
      },
    },
    {
      test: {
        kind: kind.LIST,
        elem: {
          kind: kind.UINT16,
          name: 'namedUint16'
        }
      },
      expected: {
        kind: kind.LIST,
        name: '',
        elem: {
          kind: kind.UINT16,
          name: 'namedUint16'
        }
      }
    },
    {
      test: {
        kind: kind.UNION,
        name: 'unionName',
        fields: [
          {
            name: 'A',
            type: types.INT16
          },
          {
            name: 'B',
            type: {
              kind: kind.SET,
              key: types.BOOL
            }
          }
        ]
      },
      expected: {
        kind: kind.UNION,
        name: 'unionName',
        fields: [
          {
            name: 'A',
            type: types.INT16
          },
          {
            name: 'B',
            type: {
              name: '',
              kind: kind.SET,
              key: types.BOOL
            }
          }
        ]
      },
    },
    {
      test: {
        kind: kind.MAP,
        key: {
          kind: kind.INT16,
          name: 'namedInt16'
        },
        elem: {
          kind: kind.INT32,
          name: 'namedInt32'
        }
      },
      expected: {
        kind: kind.MAP,
        name: '',
        key: {
          kind: kind.INT16,
          name: 'namedInt16'
        },
        elem: {
          kind: kind.INT32,
          name: 'namedInt32'
        }
      },
    }
  ];

  var promises = [];
  for (var i = 0; i < tests.length; i++) {
    promises.push(encodeDecodeType(t, tests[i].test, tests[i].expected));
  }
  Promise.all(promises).then(function() {
    t.end();
  }, t.end);
});

var UPPER_LOOP_LIMIT = 100;
function encodeDecodeType(t, test, expected) {
  // If the expected result is not given, use the test value instead.
  expected = expected || test;

  var writer = new ByteArrayMessageWriter();
  var typeEncoder = new TypeEncoder();
  var id = typeEncoder.encodeType(writer, test);

  var typeDecoder = new TypeDecoder();
  var reader = new TypeMessageReader(writer.getBytes());
  var j = 1;
  return readMessage();
  function readMessage() {
    return reader.nextMessage().then(function(message) {
      if (message === null) {
        var resultType = typeDecoder.lookupType(id);
        var resultStr = stringify(resultType);
        var expectedStr = stringify(expected);
        return t.equals(resultStr, expectedStr);
      }
      if (j === UPPER_LOOP_LIMIT) {
        return t.fail('read too many messages');
      }
      j++;
      return typeDecoder.defineType(message.typeId, message.messageBytes).
        then(readMessage);
    });
  }
}

// This tests a subset of potential type encoding errors.
test('type encoding encode errors', function(t) {
  var badTypes = {
    'no type': undefined,
    'no kind': {},
    'invalid kind': {
      kind: 'non-integer'
    },
    'unknown kind': {
      kind: -1
    },
    'list w/ bad elem': {
      kind: kind.LIST,
      name: 'testList',
      elem: true
    },
    'array w/ bad len': {
      kind: kind.ARRAY,
      name: 'testArray',
      elem: types.UINT64,
      len: -1
    },
    'set w/ labels': {
      kind: kind.SET,
      key: types.ANY,
      labels: ['labels', 'are', 'for', 'enums', 'only']
    },
    'enum w/ non-string labels': {
      kind: kind.ENUM,
      labels: ['do not', 'put a number in', 'the enum labels', 3]
    },
    'union w/o fields': {
      kind: kind.UNION,
      fields: []
    }
  };

  for (var testName in badTypes) {
    if (badTypes.hasOwnProperty(testName)) {
      var test = badTypes[testName];

      var writer = new ByteArrayMessageWriter();
      var typeEncoder = new TypeEncoder();
      t.throws(
        typeEncoder.encodeType.bind(typeEncoder, writer, test),
        testName
      );
    }
  }
  t.end();
});
