/// Decodes bytes using the correct name. See [decodeBytes].
library char_encodings;

import 'dart:collection';
import 'package:utf/utf.dart';

// TODO(jmesserly): this function is conspicuously absent from dart:utf.
/// Returns true if the [bytes] starts with a UTF-8 byte order mark.
/// Since UTF-8 doesn't have byte order, it's somewhat of a misnomer, but it is
/// used in HTML to detect the UTF-
bool hasUtf8Bom(List<int> bytes, [int offset = 0, int length]) {
  int end = length != null ? offset + length : bytes.length;
  return (offset + 3) <= end &&
      bytes[offset] == 0xEF &&
      bytes[offset + 1] == 0xBB &&
      bytes[offset + 2] == 0xBF;
}

// TODO(jmesserly): it's unfortunate that this has to be one-shot on the entire
// file, but dart:utf does not expose stream-based decoders yet.
/// Decodes the [bytes] with the provided [encoding] and returns an iterable for
/// the codepoints. Supports the major unicode encodings as well as ascii and
/// and windows-1252 encodings.
Iterable<int> decodeBytes(String encoding, List<int> bytes,
    [int offset = 0,
    int length,
    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
  if (length == null) length = bytes.length;
  final replace = replacementCodepoint;
  switch (encoding) {
    case 'ascii':
      bytes = bytes.sublist(offset, offset + length);
      // TODO(jmesserly): this was taken from runtime/bin/string_stream.dart
      for (int byte in bytes) {
        if (byte > 127) {
          // TODO(jmesserly): ideally this would be DecoderException, like the
          // one thrown in runtime/bin/string_stream.dart, but we don't want to
          // depend on dart:io.
          throw FormatException("Illegal ASCII character $byte");
        }
      }
      return bytes;

    case 'windows-1252':
    case 'cp1252':
      return decodeWindows1252AsIterable(bytes, offset, length, replace);

    case 'utf-8':
      // NOTE: to match the behavior of the other decode functions, we eat the
      // utf-8 BOM here.
      if (hasUtf8Bom(bytes, offset, length)) {
        offset += 3;
        length -= 3;
      }
      return decodeUtf8AsIterable(bytes, offset, length, replace);

    case 'utf-16':
      return decodeUtf16AsIterable(bytes, offset, length, replace);
    case 'utf-16-be':
      return decodeUtf16beAsIterable(bytes, offset, length, true, replace);
    case 'utf-16-le':
      return decodeUtf16leAsIterable(bytes, offset, length, true, replace);

    case 'utf-32':
      return decodeUtf32AsIterable(bytes, offset, length, replace);
    case 'utf-32-be':
      return decodeUtf32beAsIterable(bytes, offset, length, true, replace);
    case 'utf-32-le':
      return decodeUtf32leAsIterable(bytes, offset, length, true, replace);

    default:
      throw ArgumentError('Encoding $encoding not supported');
  }
}

// TODO(jmesserly): use dart:utf once http://dartbug.com/6476 is fixed.
/// Returns the code points for the [input]. This works like [String.charCodes]
/// but it decodes UTF-16 surrogate pairs.
List<int> toCodepoints(String input) {
  var newCodes = <int>[];
  for (int i = 0; i < input.length; i++) {
    var c = input.codeUnitAt(i);
    if (0xD800 <= c && c <= 0xDBFF) {
      int next = i + 1;
      if (next < input.length) {
        var d = input.codeUnitAt(next);
        if (0xDC00 <= d && d <= 0xDFFF) {
          c = 0x10000 + ((c - 0xD800) << 10) + (d - 0xDC00);
          i = next;
        }
      }
    }
    newCodes.add(c);
  }
  return newCodes;
}

/// Decodes [windows-1252](http://en.wikipedia.org/wiki/Windows-1252) bytes as
/// an iterable. Thus, the consumer can only convert as much of the input as
/// needed. Set the [replacementCharacter] to null to throw an [ArgumentError]
/// rather than replace the bad value.
IterableWindows1252Decoder decodeWindows1252AsIterable(List<int> bytes,
    [int offset = 0,
    int length,
    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
  return IterableWindows1252Decoder(
      bytes, offset, length, replacementCodepoint);
}

/// Return type of [decodeWindows1252AsIterable] and variants. The Iterable type
/// provides an iterator on demand and the iterator will only translate bytes
/// as requested by the user of the iterator. (Note: results are not cached.)
class IterableWindows1252Decoder extends IterableBase<int> {
  final List<int> bytes;
  final int offset;
  final int length;
  final int replacementCodepoint;

  IterableWindows1252Decoder(this.bytes,
      [this.offset = 0,
      this.length,
      this.replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]);

  Windows1252Decoder get iterator =>
      Windows1252Decoder(bytes, offset, length, replacementCodepoint);
}

/// Provides an iterator of Unicode codepoints from windows-1252 encoded bytes.
/// The parameters can set an offset into a list of bytes (as int), limit the
/// length of the values to be decoded, and override the default Unicode
/// replacement character. Set the replacementCharacter to null to throw an
/// ArgumentError rather than replace the bad value. The return value
/// from this method can be used as an Iterable (e.g. in a for-loop).
class Windows1252Decoder implements Iterator<int> {
  final int replacementCodepoint;
  final List<int> _bytes;
  int _offset;
  final int _length;

  Windows1252Decoder(List<int> bytes,
      [int offset = 0,
      int length,
      this.replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT])
      : _bytes = bytes,
        _offset = offset - 1,
        _length = length == null ? bytes.length : length;

  bool get _inRange => _offset >= 0 && _offset < _length;
  int get current => _inRange ? _mapChar(_bytes[_offset]) : null;

  bool moveNext() {
    _offset++;
    return _inRange;
  }

  int _mapChar(int char) {
    // TODO(jmesserly): this is duplicating entitiesWindows1252 and
    // replacementCharacters from constants.dart
    switch (char) {
      case 0x80:
        return 0x20AC; // EURO SIGN
      case 0x82:
        return 0x201A; // SINGLE LOW-9 QUOTATION MARK
      case 0x83:
        return 0x0192; // LATIN SMALL LETTER F WITH HOOK
      case 0x84:
        return 0x201E; // DOUBLE LOW-9 QUOTATION MARK
      case 0x85:
        return 0x2026; // HORIZONTAL ELLIPSIS
      case 0x86:
        return 0x2020; // DAGGER
      case 0x87:
        return 0x2021; // DOUBLE DAGGER
      case 0x88:
        return 0x02C6; // MODIFIER LETTER CIRCUMFLEX ACCENT
      case 0x89:
        return 0x2030; // PER MILLE SIGN
      case 0x8A:
        return 0x0160; // LATIN CAPITAL LETTER S WITH CARON
      case 0x8B:
        return 0x2039; // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
      case 0x8C:
        return 0x0152; // LATIN CAPITAL LIGATURE OE
      case 0x8E:
        return 0x017D; // LATIN CAPITAL LETTER Z WITH CARON
      case 0x91:
        return 0x2018; // LEFT SINGLE QUOTATION MARK
      case 0x92:
        return 0x2019; // RIGHT SINGLE QUOTATION MARK
      case 0x93:
        return 0x201C; // LEFT DOUBLE QUOTATION MARK
      case 0x94:
        return 0x201D; // RIGHT DOUBLE QUOTATION MARK
      case 0x95:
        return 0x2022; // BULLET
      case 0x96:
        return 0x2013; // EN DASH
      case 0x97:
        return 0x2014; // EM DASH
      case 0x98:
        return 0x02DC; // SMALL TILDE
      case 0x99:
        return 0x2122; // TRADE MARK SIGN
      case 0x9A:
        return 0x0161; // LATIN SMALL LETTER S WITH CARON
      case 0x9B:
        return 0x203A; // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
      case 0x9C:
        return 0x0153; // LATIN SMALL LIGATURE OE
      case 0x9E:
        return 0x017E; // LATIN SMALL LETTER Z WITH CARON
      case 0x9F:
        return 0x0178; // LATIN CAPITAL LETTER Y WITH DIAERESIS

      case 0x81:
      case 0x8D:
      case 0x8F:
      case 0x90:
      case 0x9D:
        if (replacementCodepoint == null) {
          throw ArgumentError(
              "Invalid windows-1252 code point $char at $_offset");
        }
        return replacementCodepoint;
    }
    return char;
  }
}
