// 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 latin1Strings = ["pure ascii", "blåbærgrød", "\x00 edge cases \xff"];

var nonLatin1Strings = ["Edge case \u{100}", "Edge case super-BMP \u{10000}"];

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

void testDirectConversions() {
  for (var codec in [latin1, new Latin1Codec()]) {
    for (var latin1String in latin1Strings) {
      List bytes = codec.encoder.convert(latin1String);
      Expect.listEquals(latin1String.codeUnits.toList(), bytes, latin1String);
      String roundTripString = codec.decoder.convert(bytes);
      Expect.equals(latin1String, roundTripString);
      roundTripString = codec.decode(bytes);
      Expect.equals(latin1String, roundTripString);
    }

    for (var nonLatin1String in nonLatin1Strings) {
      Expect.throws(() {
        print(codec.encoder.convert(nonLatin1String));
      }, null, nonLatin1String);
    }

    var encode = codec.encoder.convert;
    Expect.listEquals([0x42, 0xff, 0x44], encode("AB\xffDE", 1, 4));
    Expect.listEquals([0x42, 0xff, 0x44, 0x45], encode("AB\xffDE", 1));
    Expect.listEquals([0x42, 0xff, 0x44], encode("\u3000B\xffD\u3000", 1, 4));
    Expect.throws(() {
      encode("\u3000B\xffD\u3000", 0, 4);
    });
    Expect.throws(() {
      encode("\u3000B\xffD\u3000", 1);
    });
    Expect.throws(() {
      encode("\u3000B\xffD\u3000", 1, 5);
    });
    Expect.throws(() {
      encode("\u3000B\xffD\u3000", -1, 4);
    });
    Expect.throws(() {
      encode("\u3000B\xffD\u3000", 1, -1);
    });
    Expect.throws(() {
      encode("\u3000B\xffD\u3000", 3, 2);
    });

    var decode = codec.decoder.convert;
    Expect.equals("B\xffD", decode([0x41, 0x42, 0xff, 0x44, 0x45], 1, 4));
    Expect.equals("B\xffDE", decode([0x41, 0x42, 0xff, 0x44, 0x45], 1));
    Expect.equals("B\xffD", decode([0xFF, 0x42, 0xff, 0x44, 0xFF], 1, 4));
    Expect.throws(() {
      decode([0x3000, 0x42, 0xff, 0x44, 0x3000], 0, 4);
    });
    Expect.throws(() {
      decode([0x3000, 0x42, 0xff, 0x44, 0x3000], 1);
    });
    Expect.throws(() {
      decode([0x3000, 0x42, 0xff, 0x44, 0x3000], 1, 5);
    });
    Expect.throws(() {
      decode([0x3000, 0x42, 0xff, 0x44, 0x3000], -1, 4);
    });
    Expect.throws(() {
      decode([0x3000, 0x42, 0xff, 0x44, 0x3000], 1, -1);
    });
    Expect.throws(() {
      decode([0x3000, 0x42, 0xff, 0x44, 0x3000], 3, 2);
    });
  }

  var allowInvalidCodec = new Latin1Codec(allowInvalid: true);
  var invalidBytes = [0, 1, 0xff, 0xdead, 0];
  String decoded = allowInvalidCodec.decode(invalidBytes);
  Expect.equals("\x00\x01\xFF\uFFFD\x00", decoded);
  decoded = allowInvalidCodec.decoder.convert(invalidBytes);
  Expect.equals("\x00\x01\xFF\uFFFD\x00", decoded);
  decoded = latin1.decode(invalidBytes, allowInvalid: true);
  Expect.equals("\x00\x01\xFF\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 [
    latin1.encoder,
    new Latin1Codec().encoder,
    new Latin1Encoder()
  ]) {
    for (int chunkSize in [1, 2, 5, 50]) {
      for (var latin1String in latin1Strings) {
        var units = latin1String.codeUnits.toList();
        List bytes = encode(latin1String, chunkSize, converter);
        Expect.listEquals(units, bytes);
      }
      for (var nonLatin1String in nonLatin1Strings) {
        Expect.throws(() {
          encode(nonLatin1String, chunkSize, converter);
        });
      }
    }
  }
  // Check decoding.
  for (var converter in [
    latin1.decoder,
    new Latin1Codec().decoder,
    new Latin1Decoder()
  ]) {
    for (int chunkSize in [1, 2, 5, 50]) {
      for (var latin1String in latin1Strings) {
        var units = latin1String.codeUnits.toList();
        Expect.equals(latin1String, decode(units, chunkSize, converter));
      }
      for (var nonLatin1String in nonLatin1Strings) {
        var units = nonLatin1String.codeUnits.toList();
        Expect.throws(() {
          decode(units, chunkSize, converter);
        });
      }
    }
  }
}
