// 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.

// @dart = 2.9

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 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));
      }, null, 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);
        });
      }
    }
  }
}
