// Copyright (c) 2014, 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 'dart:math';

import 'package:analyzer_plugin/src/utilities/string_utilities.dart';

/**
 * "$"
 */
const int CHAR_DOLLAR = 0x24;

/**
 * "_"
 */
const int CHAR_UNDERSCORE = 0x5F;

String capitalize(String str) {
  if (isEmpty(str)) {
    return str;
  }
  return str.substring(0, 1).toUpperCase() + str.substring(1);
}

int compareStrings(String a, String b) {
  if (a == b) {
    return 0;
  }
  if (a == null) {
    return 1;
  }
  if (b == null) {
    return -1;
  }
  return a.compareTo(b);
}

/**
 * Return a simple difference between the given [oldStr] and [newStr].
 */
SimpleDiff computeSimpleDiff(String oldStr, String newStr) {
  int prefixLength = findCommonPrefix(oldStr, newStr);
  int suffixLength = findCommonSuffix(oldStr, newStr);
  while (prefixLength >= 0) {
    int oldReplaceLength = oldStr.length - prefixLength - suffixLength;
    int newReplaceLength = newStr.length - prefixLength - suffixLength;
    if (oldReplaceLength >= 0 && newReplaceLength >= 0) {
      return new SimpleDiff(prefixLength, oldReplaceLength,
          newStr.substring(prefixLength, newStr.length - suffixLength));
    }
    prefixLength--;
  }
  return new SimpleDiff(0, oldStr.length, newStr);
}

int countLeadingWhitespaces(String str) {
  int i = 0;
  for (; i < str.length; i++) {
    int c = str.codeUnitAt(i);
    if (!isWhitespace(c)) {
      break;
    }
  }
  return i;
}

/**
 * Counts how many times [sub] appears in [str].
 */
int countMatches(String str, String sub) {
  if (isEmpty(str) || isEmpty(sub)) {
    return 0;
  }
  int count = 0;
  int idx = 0;
  while ((idx = str.indexOf(sub, idx)) != -1) {
    count++;
    idx += sub.length;
  }
  return count;
}

int countTrailingWhitespaces(String str) {
  int i = 0;
  for (; i < str.length; i++) {
    int c = str.codeUnitAt(str.length - 1 - i);
    if (!isWhitespace(c)) {
      break;
    }
  }
  return i;
}

/**
 * Return the number of characters common to the start of [a] and [b].
 */
int findCommonPrefix(String a, String b) {
  int n = min(a.length, b.length);
  for (int i = 0; i < n; i++) {
    if (a.codeUnitAt(i) != b.codeUnitAt(i)) {
      return i;
    }
  }
  return n;
}

/**
 * Return the number of characters common to the end of [a] and [b].
 */
int findCommonSuffix(String a, String b) {
  int a_length = a.length;
  int b_length = b.length;
  int n = min(a_length, b_length);
  for (int i = 1; i <= n; i++) {
    if (a.codeUnitAt(a_length - i) != b.codeUnitAt(b_length - i)) {
      return i - 1;
    }
  }
  return n;
}

/**
 * Checks if [str] is `null`, empty or is whitespace.
 */
bool isBlank(String str) {
  if (str == null) {
    return true;
  }
  if (str.isEmpty) {
    return true;
  }
  return str.codeUnits.every(isSpace);
}

bool isDigit(int c) {
  return c >= 0x30 && c <= 0x39;
}

bool isEOL(int c) {
  return c == 0x0D || c == 0x0A;
}

bool isLetter(int c) {
  return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A);
}

bool isLetterOrDigit(int c) {
  return isLetter(c) || isDigit(c);
}

bool isSpace(int c) => c == 0x20 || c == 0x09;

bool isWhitespace(int c) {
  return isSpace(c) || isEOL(c);
}

String removeEnd(String str, String remove) {
  if (isEmpty(str) || isEmpty(remove)) {
    return str;
  }
  if (str.endsWith(remove)) {
    return str.substring(0, str.length - remove.length);
  }
  return str;
}

String repeat(String s, int n) {
  StringBuffer sb = new StringBuffer();
  for (int i = 0; i < n; i++) {
    sb.write(s);
  }
  return sb.toString();
}

/**
 * If the [text] length is above the [limit], replace the middle with `...`.
 */
String shorten(String text, int limit) {
  if (text.length > limit) {
    int headLength = limit ~/ 2 - 1;
    int tailLength = limit - headLength - 3;
    return text.substring(0, headLength) +
        '...' +
        text.substring(text.length - tailLength);
  }
  return text;
}

/**
 * Information about a single replacement that should be made to convert the
 * "old" string to the "new" one.
 */
class SimpleDiff {
  final int offset;
  final int length;
  final String replacement;

  SimpleDiff(this.offset, this.length, this.replacement);
}
