// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import "package:expect/expect.dart";
import 'dart:convert';

var asciiStrings = [
  "pure ascii",
  "\x00 with control characters \n",
  "\x01 edge cases \x7f"
];

var nonAsciiStrings = [
  "\x80 edge case first",
  "Edge case ASCII \u{80}",
  "Edge case byte \u{ff}",
  "Edge case super-BMP \u{10000}"
];

void main() {
  // Build longer versions of the example strings.
  for (int i = 0, n = asciiStrings.length; i < n; i++) {
    var string = asciiStrings[i];
    while (string.length < 1024) {
      string += string;
    }
    asciiStrings.add(string);
  }
  for (int i = 0, n = nonAsciiStrings.length; i < n; i++) {
    var string = nonAsciiStrings[i];
    while (string.length < 1024) {
      string += string;
    }
    nonAsciiStrings.add(string);
  }
  testDirectConversions();
  testChunkedConversions();
}

void testDirectConversions() {
  for (var codec in [ascii, new AsciiCodec()]) {
    for (var asciiString in asciiStrings) {
      List<int> bytes = codec.encoder.convert(asciiString);
      Expect.listEquals(asciiString.codeUnits.toList(), bytes, asciiString);
      String roundTripString = codec.decoder.convert(bytes);
      Expect.equals(asciiString, roundTripString);
      roundTripString = codec.decode(bytes);
      Expect.equals(asciiString, roundTripString);
    }

    for (var nonAsciiString in nonAsciiStrings) {
      Expect.throws(() {
        print(codec.encoder.convert(nonAsciiString));
      }, (_) => true, nonAsciiString);
    }

    var encode = codec.encoder.convert;
    Expect.listEquals([0x42, 0x43, 0x44], encode("ABCDE", 1, 4));
    Expect.listEquals([0x42, 0x43, 0x44, 0x45], encode("ABCDE", 1));
    Expect.listEquals([0x42, 0x43, 0x44], encode("\xffBCD\xff", 1, 4));
    Expect.throws(() {
      encode("\xffBCD\xff", 0, 4);
    });
    Expect.throws(() {
      encode("\xffBCD\xff", 1);
    });
    Expect.throws(() {
      encode("\xffBCD\xff", 1, 5);
    });
    Expect.throws(() {
      encode("\xffBCD\xff", -1, 4);
    });
    Expect.throws(() {
      encode("\xffBCD\xff", 1, -1);
    });
    Expect.throws(() {
      encode("\xffBCD\xff", 3, 2);
    });

    var decode = codec.decoder.convert;
    Expect.equals("BCD", decode([0x41, 0x42, 0x43, 0x44, 0x45], 1, 4));
    Expect.equals("BCDE", decode([0x41, 0x42, 0x43, 0x44, 0x45], 1));
    Expect.equals("BCD", decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 1, 4));
    Expect.throws(() {
      decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 0, 4);
    });
    Expect.throws(() {
      decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 1);
    });
    Expect.throws(() {
      decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 1, 5);
    });
    Expect.throws(() {
      decode([0xFF, 0x42, 0x43, 0x44, 0xFF], -1, 4);
    });
    Expect.throws(() {
      decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 1, -1);
    });
    Expect.throws(() {
      decode([0xFF, 0x42, 0x43, 0x44, 0xFF], 3, 2);
    });
  }

  var allowInvalidCodec = new AsciiCodec(allowInvalid: true);
  var invalidBytes = [0, 1, 0xff, 0xdead, 0];
  String decoded = allowInvalidCodec.decode(invalidBytes);
  Expect.equals("\x00\x01\uFFFD\uFFFD\x00", decoded);
  decoded = allowInvalidCodec.decoder.convert(invalidBytes);
  Expect.equals("\x00\x01\uFFFD\uFFFD\x00", decoded);
  decoded = ascii.decode(invalidBytes, allowInvalid: true);
  Expect.equals("\x00\x01\uFFFD\uFFFD\x00", decoded);
}

List<int> encode(
    String str, int chunkSize, Converter<String, List<int>> converter) {
  List<int> bytes = <int>[];
  var byteSink = new ByteConversionSink.withCallback(bytes.addAll);
  var stringConversionSink = converter.startChunkedConversion(byteSink);
  for (int i = 0; i < str.length; i += chunkSize) {
    if (i + chunkSize <= str.length) {
      stringConversionSink.add(str.substring(i, i + chunkSize));
    } else {
      stringConversionSink.add(str.substring(i));
    }
  }
  stringConversionSink.close();
  return bytes;
}

String decode(
    List<int> bytes, int chunkSize, Converter<List<int>, String> converter) {
  StringBuffer buf = new StringBuffer();
  var stringSink = new StringConversionSink.fromStringSink(buf);
  var byteConversionSink = converter.startChunkedConversion(stringSink);
  for (int i = 0; i < bytes.length; i += chunkSize) {
    if (i + chunkSize <= bytes.length) {
      byteConversionSink.add(bytes.sublist(i, i + chunkSize));
    } else {
      byteConversionSink.add(bytes.sublist(i));
    }
  }
  byteConversionSink.close();
  return buf.toString();
}

void testChunkedConversions() {
  // Check encoding.
  for (var converter in [
    ascii.encoder,
    new AsciiCodec().encoder,
    new AsciiEncoder()
  ]) {
    for (int chunkSize in [1, 2, 5, 50]) {
      for (var asciiString in asciiStrings) {
        var units = asciiString.codeUnits.toList();
        List bytes = encode(asciiString, chunkSize, converter);
        Expect.listEquals(units, bytes);
      }
      for (var nonAsciiString in nonAsciiStrings) {
        Expect.throws(() {
          encode(nonAsciiString, chunkSize, converter);
        });
      }
    }
  }
  // Check decoding.
  for (var converter in [
    ascii.decoder,
    new AsciiCodec().decoder,
    new AsciiDecoder()
  ]) {
    for (int chunkSize in [1, 2, 5, 50]) {
      for (var asciiString in asciiStrings) {
        var units = asciiString.codeUnits.toList();
        Expect.equals(asciiString, decode(units, chunkSize, converter));
      }
      for (var nonAsciiString in nonAsciiStrings) {
        var units = nonAsciiString.codeUnits.toList();
        Expect.throws(() {
          decode(units, chunkSize, converter);
        });
      }
    }
  }
}
