// Copyright (c) 2016, 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.

library fasta.quote;

import 'deprecated_problems.dart' show deprecated_inputError;

import 'problems.dart' show unhandled;

import 'scanner/characters.dart'
    show
        $BACKSLASH,
        $BS,
        $CLOSE_CURLY_BRACKET,
        $CR,
        $FF,
        $LF,
        $OPEN_CURLY_BRACKET,
        $SPACE,
        $TAB,
        $VTAB,
        $b,
        $f,
        $n,
        $r,
        $t,
        $u,
        $v,
        $x,
        hexDigitValue,
        isHexDigit;

enum Quote {
  Single,
  Double,
  MultiLineSingle,
  MultiLineDouble,
  RawSingle,
  RawDouble,
  RawMultiLineSingle,
  RawMultiLineDouble,
}

Quote analyzeQuote(String first) {
  if (first.startsWith('"""')) return Quote.MultiLineDouble;
  if (first.startsWith('r"""')) return Quote.RawMultiLineDouble;
  if (first.startsWith("'''")) return Quote.MultiLineSingle;
  if (first.startsWith("r'''")) return Quote.RawMultiLineSingle;
  if (first.startsWith('"')) return Quote.Double;
  if (first.startsWith('r"')) return Quote.RawDouble;
  if (first.startsWith("'")) return Quote.Single;
  if (first.startsWith("r'")) return Quote.RawSingle;
  return unhandled(first, "analyzeQuote", -1, null);
}

// Note: based on [StringValidator.quotingFromString]
// (pkg/compiler/lib/src/string_validator.dart).
int lengthOfOptionalWhitespacePrefix(String first, int start) {
  List<int> codeUnits = first.codeUnits;
  for (int i = start; i < codeUnits.length; i++) {
    int code = codeUnits[i];
    if (code == $BACKSLASH) {
      i++;
      if (i < codeUnits.length) {
        code = codeUnits[i];
      } else {
        break;
      }
    }
    if (code == $TAB || code == $SPACE) continue;
    if (code == $CR) {
      if (i + 1 < codeUnits.length && codeUnits[i + 1] == $LF) {
        i++;
      }
      return i + 1;
    }
    if (code == $LF) {
      return i + 1;
    }
    break; // Not a white-space character.
  }
  return start;
}

int firstQuoteLength(String first, Quote quote) {
  switch (quote) {
    case Quote.Single:
    case Quote.Double:
      return 1;

    case Quote.MultiLineSingle:
    case Quote.MultiLineDouble:
      return lengthOfOptionalWhitespacePrefix(first, 3);

    case Quote.RawSingle:
    case Quote.RawDouble:
      return 2;

    case Quote.RawMultiLineSingle:
    case Quote.RawMultiLineDouble:
      return lengthOfOptionalWhitespacePrefix(first, 4);
  }
  return unhandled("$quote", "firstQuoteLength", -1, null);
}

int lastQuoteLength(Quote quote) {
  switch (quote) {
    case Quote.Single:
    case Quote.Double:
    case Quote.RawSingle:
    case Quote.RawDouble:
      return 1;

    case Quote.MultiLineSingle:
    case Quote.MultiLineDouble:
    case Quote.RawMultiLineSingle:
    case Quote.RawMultiLineDouble:
      return 3;
  }
  return unhandled("$quote", "lastQuoteLength", -1, null);
}

String unescapeFirstStringPart(String first, Quote quote) {
  return unescape(first.substring(firstQuoteLength(first, quote)), quote);
}

String unescapeLastStringPart(String last, Quote quote) {
  return unescape(
      last.substring(0, last.length - lastQuoteLength(quote)), quote);
}

String unescapeString(String string) {
  Quote quote = analyzeQuote(string);
  return unescape(
      string.substring(firstQuoteLength(string, quote),
          string.length - lastQuoteLength(quote)),
      quote);
}

String unescape(String string, Quote quote) {
  switch (quote) {
    case Quote.Single:
    case Quote.Double:
      return !string.contains("\\")
          ? string
          : unescapeCodeUnits(string.codeUnits, false);

    case Quote.MultiLineSingle:
    case Quote.MultiLineDouble:
      return !string.contains("\\") && !string.contains("\r")
          ? string
          : unescapeCodeUnits(string.codeUnits, false);

    case Quote.RawSingle:
    case Quote.RawDouble:
      return string;

    case Quote.RawMultiLineSingle:
    case Quote.RawMultiLineDouble:
      return !string.contains("\r")
          ? string
          : unescapeCodeUnits(string.codeUnits, true);
  }
  return unhandled("$quote", "unescape", -1, null);
}

const String incompleteSequence = "Incomplete escape sequence.";

const String invalidCharacter = "Invalid character in escape sequence.";

const String invalidCodePoint = "Invalid code point.";

// Note: based on
// [StringValidator.validateString](pkg/compiler/lib/src/string_validator.dart).
String unescapeCodeUnits(List<int> codeUnits, bool isRaw) {
  // Can't use Uint8List or Uint16List here, the code units may be larger.
  List<int> result = new List<int>(codeUnits.length);
  int resultOffset = 0;
  error(int offset, String message) {
    deprecated_inputError(null, null, message);
  }

  for (int i = 0; i < codeUnits.length; i++) {
    int code = codeUnits[i];
    if (code == $CR) {
      if (i + 1 < codeUnits.length && codeUnits[i + 1] == $LF) {
        i++;
      }
      code = $LF;
    } else if (!isRaw && code == $BACKSLASH) {
      if (codeUnits.length == ++i) return error(i, incompleteSequence);
      code = codeUnits[i];

      /// `\n` for newline, equivalent to `\x0A`.
      /// `\r` for carriage return, equivalent to `\x0D`.
      /// `\f` for form feed, equivalent to `\x0C`.
      /// `\b` for backspace, equivalent to `\x08`.
      /// `\t` for tab, equivalent to `\x09`.
      /// `\v` for vertical tab, equivalent to `\x0B`.
      /// `\xXX` for hex escape.
      /// `\uXXXX` or `\u{XX?X?X?X?X?}` for Unicode hex escape.
      if (code == $n) {
        code = $LF;
      } else if (code == $r) {
        code = $CR;
      } else if (code == $f) {
        code = $FF;
      } else if (code == $b) {
        code = $BS;
      } else if (code == $t) {
        code = $TAB;
      } else if (code == $v) {
        code = $VTAB;
      } else if (code == $x) {
        // Expect exactly 2 hex digits.
        if (codeUnits.length <= i + 2) return error(i, incompleteSequence);
        code = 0;
        for (int j = 0; j < 2; j++) {
          int digit = codeUnits[++i];
          if (!isHexDigit(digit)) return error(i, invalidCharacter);
          code = (code << 4) + hexDigitValue(digit);
        }
      } else if (code == $u) {
        if (codeUnits.length == i + 1) return error(i, incompleteSequence);
        code = codeUnits[i + 1];
        if (code == $OPEN_CURLY_BRACKET) {
          // Expect 1-6 hex digits followed by '}'.
          if (codeUnits.length == ++i) return error(i, incompleteSequence);
          code = 0;
          for (int j = 0; j < 7; j++) {
            if (codeUnits.length == ++i) return error(i, incompleteSequence);
            int digit = codeUnits[i];
            if (j != 0 && digit == $CLOSE_CURLY_BRACKET) break;
            if (!isHexDigit(digit)) return error(i, invalidCharacter);
            code = (code << 4) + hexDigitValue(digit);
          }
        } else {
          // Expect exactly 4 hex digits.
          if (codeUnits.length <= i + 4) return error(i, incompleteSequence);
          code = 0;
          for (int j = 0; j < 4; j++) {
            int digit = codeUnits[++i];
            if (!isHexDigit(digit)) return error(i, invalidCharacter);
            code = (code << 4) + hexDigitValue(digit);
          }
        }
      } else {
        // Nothing, escaped character is passed through;
      }
      if (code > 0x10FFFF) return error(i, invalidCodePoint);
    }
    result[resultOffset++] = code;
  }
  return new String.fromCharCodes(result, 0, resultOffset);
}
