/**
 * @fileoverview Tests for reader.js.
 */
goog.module('protobuf.binary.ReaderTest');

goog.setTestOnly();

// Note to the reader:
// Since the reader behavior changes with the checking level some of the
// tests in this file have to know which checking level is enable to make
// correct assertions.
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
const ByteString = goog.require('protobuf.ByteString');
const reader = goog.require('protobuf.binary.reader');
const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks');
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
const {encode} = goog.require('protobuf.binary.textencoding');
const {getBoolPairs} = goog.require('protobuf.binary.boolTestPairs');
const {getDoublePairs} = goog.require('protobuf.binary.doubleTestPairs');
const {getFixed32Pairs} = goog.require('protobuf.binary.fixed32TestPairs');
const {getFloatPairs} = goog.require('protobuf.binary.floatTestPairs');
const {getInt32Pairs} = goog.require('protobuf.binary.int32TestPairs');
const {getInt64Pairs} = goog.require('protobuf.binary.int64TestPairs');
const {getPackedBoolPairs} = goog.require('protobuf.binary.packedBoolTestPairs');
const {getPackedDoublePairs} = goog.require('protobuf.binary.packedDoubleTestPairs');
const {getPackedFixed32Pairs} = goog.require('protobuf.binary.packedFixed32TestPairs');
const {getPackedFloatPairs} = goog.require('protobuf.binary.packedFloatTestPairs');
const {getPackedInt32Pairs} = goog.require('protobuf.binary.packedInt32TestPairs');
const {getPackedInt64Pairs} = goog.require('protobuf.binary.packedInt64TestPairs');
const {getPackedSfixed32Pairs} = goog.require('protobuf.binary.packedSfixed32TestPairs');
const {getPackedSfixed64Pairs} = goog.require('protobuf.binary.packedSfixed64TestPairs');
const {getPackedSint32Pairs} = goog.require('protobuf.binary.packedSint32TestPairs');
const {getPackedSint64Pairs} = goog.require('protobuf.binary.packedSint64TestPairs');
const {getPackedUint32Pairs} = goog.require('protobuf.binary.packedUint32TestPairs');
const {getSfixed32Pairs} = goog.require('protobuf.binary.sfixed32TestPairs');
const {getSfixed64Pairs} = goog.require('protobuf.binary.sfixed64TestPairs');
const {getSint32Pairs} = goog.require('protobuf.binary.sint32TestPairs');
const {getSint64Pairs} = goog.require('protobuf.binary.sint64TestPairs');
const {getUint32Pairs} = goog.require('protobuf.binary.uint32TestPairs');

/******************************************************************************
 *                        Optional FUNCTIONS
 ******************************************************************************/

describe('Read bool does', () => {
  for (const pair of getBoolPairs()) {
    it(`decode ${pair.name}`, () => {
      if (pair.error && CHECK_CRITICAL_STATE) {
        expect(() => reader.readBool(pair.bufferDecoder, 0)).toThrow();
      } else {
        const d = reader.readBool(
            pair.bufferDecoder, pair.bufferDecoder.startIndex());
        expect(d).toEqual(pair.boolValue);
      }
    });
  }
});

describe('readBytes does', () => {
  it('throw exception if data is too short', () => {
    const bufferDecoder = createBufferDecoder();
    expect(() => reader.readBytes(bufferDecoder, 0)).toThrow();
  });

  it('read bytes by index', () => {
    const bufferDecoder = createBufferDecoder(3, 1, 2, 3);
    const byteString = reader.readBytes(bufferDecoder, 0);
    expect(ByteString.fromArrayBuffer(new Uint8Array([1, 2, 3]).buffer))
        .toEqual(byteString);
  });
});

describe('readDouble does', () => {
  it('throw exception if data is too short', () => {
    const bufferDecoder = createBufferDecoder();
    expect(() => reader.readDouble(bufferDecoder, 0)).toThrow();
  });

  for (const pair of getDoublePairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readDouble(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.doubleValue);
    });
  }
});

describe('readFixed32 does', () => {
  it('throw exception if data is too short', () => {
    const bufferDecoder = createBufferDecoder();
    expect(() => reader.readFixed32(bufferDecoder, 0)).toThrow();
  });

  for (const pair of getFixed32Pairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readFixed32(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.intValue);
    });
  }
});

describe('readFloat does', () => {
  it('throw exception if data is too short', () => {
    const bufferDecoder = createBufferDecoder();
    expect(() => reader.readFloat(bufferDecoder, 0)).toThrow();
  });

  for (const pair of getFloatPairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readFloat(pair.bufferDecoder, 0);
      expect(d).toEqual(Math.fround(pair.floatValue));
    });
  }
});

describe('readInt32 does', () => {
  it('throw exception if data is too short', () => {
    const bufferDecoder = createBufferDecoder(0x80);
    expect(() => reader.readInt32(bufferDecoder, 0)).toThrow();
  });

  for (const pair of getInt32Pairs()) {
    it(`decode ${pair.name}`, () => {
      if (pair.error && CHECK_CRITICAL_STATE) {
        expect(() => reader.readInt32(pair.bufferDecoder, 0)).toThrow();
      } else {
        const d = reader.readInt32(pair.bufferDecoder, 0);
        expect(d).toEqual(pair.intValue);
      }
    });
  }
});

describe('readSfixed32 does', () => {
  it('throw exception if data is too short', () => {
    const bufferDecoder = createBufferDecoder(0x80);
    expect(() => reader.readSfixed32(bufferDecoder, 0)).toThrow();
  });

  for (const pair of getSfixed32Pairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readSfixed32(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.intValue);
    });
  }
});

describe('readSfixed64 does', () => {
  it('throw exception if data is too short', () => {
    const bufferDecoder = createBufferDecoder(0x80);
    expect(() => reader.readSfixed64(bufferDecoder, 0)).toThrow();
  });

  for (const pair of getSfixed64Pairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readSfixed64(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.longValue);
    });
  }
});

describe('readSint32 does', () => {
  it('throw exception if data is too short', () => {
    const bufferDecoder = createBufferDecoder(0x80);
    expect(() => reader.readSint32(bufferDecoder, 0)).toThrow();
  });

  for (const pair of getSint32Pairs()) {
    it(`decode ${pair.name}`, () => {
      if (pair.error && CHECK_CRITICAL_STATE) {
        expect(() => reader.readSint32(pair.bufferDecoder, 0)).toThrow();
      } else {
        const d = reader.readSint32(pair.bufferDecoder, 0);
        expect(d).toEqual(pair.intValue);
      }
    });
  }
});

describe('readInt64 does', () => {
  it('throw exception if data is too short', () => {
    const bufferDecoder = createBufferDecoder(0x80);
    expect(() => reader.readInt64(bufferDecoder, 0)).toThrow();
  });

  for (const pair of getInt64Pairs()) {
    it(`decode ${pair.name}`, () => {
      if (pair.error && CHECK_CRITICAL_STATE) {
        expect(() => reader.readInt64(pair.bufferDecoder, 0)).toThrow();
      } else {
        const d = reader.readInt64(pair.bufferDecoder, 0);
        expect(d).toEqual(pair.longValue);
      }
    });
  }
});

describe('readSint64 does', () => {
  it('throw exception if data is too short', () => {
    const bufferDecoder = createBufferDecoder(0x80);
    expect(() => reader.readSint64(bufferDecoder, 0)).toThrow();
  });

  for (const pair of getSint64Pairs()) {
    it(`decode ${pair.name}`, () => {
      if (pair.error && CHECK_CRITICAL_STATE) {
        expect(() => reader.readSint64(pair.bufferDecoder, 0)).toThrow();
      } else {
        const d = reader.readSint64(pair.bufferDecoder, 0);
        expect(d).toEqual(pair.longValue);
      }
    });
  }
});

describe('readUint32 does', () => {
  it('throw exception if data is too short', () => {
    const bufferDecoder = createBufferDecoder(0x80);
    expect(() => reader.readUint32(bufferDecoder, 0)).toThrow();
  });

  for (const pair of getUint32Pairs()) {
    if (!pair.skip_reader) {
      it(`decode ${pair.name}`, () => {
        if (pair.error && CHECK_CRITICAL_STATE) {
          expect(() => reader.readUint32(pair.bufferDecoder, 0)).toThrow();
        } else {
          const d = reader.readUint32(pair.bufferDecoder, 0);
          expect(d).toEqual(pair.intValue);
        }
      });
    }
  }
});

/**
 *
 * @param {string} s
 * @return {!Uint8Array}
 */
function encodeString(s) {
  if (typeof TextEncoder !== 'undefined') {
    const textEncoder = new TextEncoder('utf-8');
    return textEncoder.encode(s);
  } else {
    return encode(s);
  }
}

/** @param {string} s */
function expectEncodedStringToMatch(s) {
  const array = encodeString(s);
  const length = array.length;
  if (length > 127) {
    throw new Error('Test only works for strings shorter than 128');
  }
  const encodedArray = new Uint8Array(length + 1);
  encodedArray[0] = length;
  encodedArray.set(array, 1);
  const bufferDecoder = BufferDecoder.fromArrayBuffer(encodedArray.buffer);
  expect(reader.readString(bufferDecoder, 0)).toEqual(s);
}

describe('readString does', () => {
  it('return empty string for zero length string', () => {
    const s = reader.readString(createBufferDecoder(0x00), 0);
    expect(s).toEqual('');
  });

  it('decode random strings', () => {
    // 1 byte strings
    expectEncodedStringToMatch('hello');
    expectEncodedStringToMatch('HELLO1!');

    // 2 byte String
    expectEncodedStringToMatch('©');

    // 3 byte string
    expectEncodedStringToMatch('❄');

    // 4 byte string
    expectEncodedStringToMatch('😁');
  });

  it('decode 1 byte strings', () => {
    for (let i = 0; i < 0x80; i++) {
      const s = String.fromCharCode(i);
      expectEncodedStringToMatch(s);
    }
  });

  it('decode 2 byte strings', () => {
    for (let i = 0xC0; i < 0x7FF; i++) {
      const s = String.fromCharCode(i);
      expectEncodedStringToMatch(s);
    }
  });

  it('decode 3 byte strings', () => {
    for (let i = 0x7FF; i < 0x8FFF; i++) {
      const s = String.fromCharCode(i);
      expectEncodedStringToMatch(s);
    }
  });

  it('throw exception on invalid bytes', () => {
    // This test will only succeed with the native TextDecoder since
    // our polyfill does not do any validation. IE10 and IE11 don't support
    // TextDecoder.
    // TODO: Remove this check once we no longer need to support IE
    if (typeof TextDecoder !== 'undefined') {
      expect(
          () => reader.readString(
              createBufferDecoder(0x01, /* invalid utf data point*/ 0xFF), 0))
          .toThrow();
    }
  });

  it('throw exception if data is too short', () => {
    const array = createBufferDecoder(0x02, '?'.charCodeAt(0));
    expect(() => reader.readString(array, 0)).toThrow();
  });
});

/******************************************************************************
 *                        REPEATED FUNCTIONS
 ******************************************************************************/

describe('readPackedBool does', () => {
  for (const pair of getPackedBoolPairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readPackedBool(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.boolValues);
    });
  }
});

describe('readPackedDouble does', () => {
  for (const pair of getPackedDoublePairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readPackedDouble(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.doubleValues);
    });
  }
});

describe('readPackedFixed32 does', () => {
  for (const pair of getPackedFixed32Pairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readPackedFixed32(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.fixed32Values);
    });
  }
});

describe('readPackedFloat does', () => {
  for (const pair of getPackedFloatPairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readPackedFloat(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.floatValues);
    });
  }
});

describe('readPackedInt32 does', () => {
  for (const pair of getPackedInt32Pairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readPackedInt32(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.int32Values);
    });
  }
});

describe('readPackedInt64 does', () => {
  for (const pair of getPackedInt64Pairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readPackedInt64(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.int64Values);
    });
  }
});

describe('readPackedSfixed32 does', () => {
  for (const pair of getPackedSfixed32Pairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readPackedSfixed32(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.sfixed32Values);
    });
  }
});

describe('readPackedSfixed64 does', () => {
  for (const pair of getPackedSfixed64Pairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readPackedSfixed64(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.sfixed64Values);
    });
  }
});

describe('readPackedSint32 does', () => {
  for (const pair of getPackedSint32Pairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readPackedSint32(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.sint32Values);
    });
  }
});

describe('readPackedSint64 does', () => {
  for (const pair of getPackedSint64Pairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readPackedSint64(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.sint64Values);
    });
  }
});

describe('readPackedUint32 does', () => {
  for (const pair of getPackedUint32Pairs()) {
    it(`decode ${pair.name}`, () => {
      const d = reader.readPackedUint32(pair.bufferDecoder, 0);
      expect(d).toEqual(pair.uint32Values);
    });
  }
});
