// 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 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/correction/strings.dart';
import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
import 'package:front_end/src/scanner/token.dart' show Keyword;

/**
 * Returns the [RefactoringStatus] with severity:
 *   OK if the name is valid;
 *   WARNING if the name is discouraged;
 *   FATAL if the name is illegal.
 */
RefactoringStatus validateClassName(String name) {
  return _validateUpperCamelCase(name, "Class");
}

/**
 * Returns the [RefactoringStatus] with severity:
 *   OK if the name is valid;
 *   WARNING if the name is discouraged;
 *   FATAL if the name is illegal.
 */
RefactoringStatus validateConstructorName(String name) {
  if (name != null && name.isEmpty) {
    return new RefactoringStatus();
  }
  return _validateLowerCamelCase(name, "Constructor");
}

/**
 * Returns the [RefactoringStatus] with severity:
 *   OK if the name is valid;
 *   WARNING if the name is discouraged;
 *   FATAL if the name is illegal.
 */
RefactoringStatus validateFieldName(String name) {
  return _validateLowerCamelCase(name, "Field");
}

/**
 * Returns the [RefactoringStatus] with severity:
 *   OK if the name is valid;
 *   WARNING if the name is discouraged;
 *   FATAL if the name is illegal.
 */
RefactoringStatus validateFunctionName(String name) {
  return _validateLowerCamelCase(name, "Function");
}

/**
 * Returns the [RefactoringStatus] with severity:
 *   OK if the name is valid;
 *   WARNING if the name is discouraged;
 *   FATAL if the name is illegal.
 */
RefactoringStatus validateFunctionTypeAliasName(String name) {
  return _validateUpperCamelCase(name, "Function type alias");
}

/**
 * Returns the [RefactoringStatus] with severity:
 *   OK if the name is valid;
 *   WARNING if the name is discouraged;
 *   FATAL if the name is illegal.
 */
RefactoringStatus validateImportPrefixName(String name) {
  if (name != null && name.isEmpty) {
    return new RefactoringStatus();
  }
  return _validateLowerCamelCase(name, "Import prefix");
}

/**
 * Returns the [RefactoringStatus] with severity:
 *   OK if the name is valid;
 *   WARNING if the name is discouraged;
 *   FATAL if the name is illegal.
 */
RefactoringStatus validateLabelName(String name) {
  return _validateLowerCamelCase(name, "Label");
}

/**
 * Returns the [RefactoringStatus] with severity:
 *   OK if the name is valid;
 *   WARNING if the name is discouraged;
 *   FATAL if the name is illegal.
 */
RefactoringStatus validateLibraryName(String name) {
  // null
  if (name == null) {
    return new RefactoringStatus.fatal("Library name must not be null.");
  }
  // blank
  if (isBlank(name)) {
    return new RefactoringStatus.fatal("Library name must not be blank.");
  }
  // check identifiers
  List<String> identifiers = name.split('.');
  for (String identifier in identifiers) {
    RefactoringStatus status = _validateIdentifier(identifier,
        "Library name identifier", "a lowercase letter or underscore");
    if (!status.isOK) {
      return status;
    }
  }
  // should not have upper-case letters
  for (String identifier in identifiers) {
    for (int c in identifier.codeUnits) {
      if (isUpperCase(c)) {
        return new RefactoringStatus.warning(
            "Library name should consist of lowercase identifier separated by dots.");
      }
    }
  }
  // OK
  return new RefactoringStatus();
}

/**
 * Returns the [RefactoringStatus] with severity:
 *   OK if the name is valid;
 *   WARNING if the name is discouraged;
 *   FATAL if the name is illegal.
 */
RefactoringStatus validateMethodName(String name) {
  return _validateLowerCamelCase(name, "Method");
}

/**
 * Returns the [RefactoringStatus] with severity:
 *   OK if the name is valid;
 *   WARNING if the name is discouraged;
 *   FATAL if the name is illegal.
 */
RefactoringStatus validateParameterName(String name) {
  return _validateLowerCamelCase(name, "Parameter");
}

/**
 * Returns the [RefactoringStatus] with severity:
 *   OK if the name is valid;
 *   WARNING if the name is discouraged;
 *   FATAL if the name is illegal.
 */
RefactoringStatus validateVariableName(String name) {
  return _validateLowerCamelCase(name, "Variable");
}

RefactoringStatus _validateIdentifier(
    String identifier, String desc, String beginDesc) {
  // has leading/trailing spaces
  String trimmed = identifier.trim();
  if (identifier != trimmed) {
    String message = "$desc must not start or end with a blank.";
    return new RefactoringStatus.fatal(message);
  }
  // empty
  int length = identifier.length;
  if (length == 0) {
    String message = "$desc must not be empty.";
    return new RefactoringStatus.fatal(message);
  }
  // keyword
  {
    Keyword keyword = Keyword.keywords[identifier];
    if (keyword != null) {
      String message = "$desc must not be a keyword.";
      return new RefactoringStatus.fatal(message);
    }
  }
  // first character
  int currentChar = identifier.codeUnitAt(0);
  if (!isLetter(currentChar) &&
      currentChar != CHAR_UNDERSCORE &&
      currentChar != CHAR_DOLLAR) {
    String message = "$desc must begin with $beginDesc.";
    return new RefactoringStatus.fatal(message);
  }
  // other characters
  for (int i = 1; i < length; i++) {
    currentChar = identifier.codeUnitAt(i);
    if (!isLetterOrDigit(currentChar) &&
        currentChar != CHAR_UNDERSCORE &&
        currentChar != CHAR_DOLLAR) {
      String charStr = new String.fromCharCode(currentChar);
      String message = "$desc must not contain '$charStr'.";
      return new RefactoringStatus.fatal(message);
    }
  }
  // OK
  return new RefactoringStatus();
}

/**
 * Validates [identifier], should be lower camel case.
 */
RefactoringStatus _validateLowerCamelCase(String identifier, String desc) {
  desc += ' name';
  // null
  if (identifier == null) {
    String message = "$desc must not be null.";
    return new RefactoringStatus.fatal(message);
  }
  // is not identifier
  RefactoringStatus status =
      _validateIdentifier(identifier, desc, "a lowercase letter or underscore");
  if (!status.isOK) {
    return status;
  }
  // is private, OK
  if (identifier.codeUnitAt(0) == CHAR_UNDERSCORE) {
    return new RefactoringStatus();
  }
  // leading $, OK
  if (identifier.codeUnitAt(0) == CHAR_DOLLAR) {
    return new RefactoringStatus();
  }
  // does not start with lower case
  if (!isLowerCase(identifier.codeUnitAt(0))) {
    String message = "$desc should start with a lowercase letter.";
    return new RefactoringStatus.warning(message);
  }
  // OK
  return new RefactoringStatus();
}

/**
 * Validate the given identifier, which should be upper camel case.
 */
RefactoringStatus _validateUpperCamelCase(String identifier, String desc) {
  desc += ' name';
  // null
  if (identifier == null) {
    String message = "$desc must not be null.";
    return new RefactoringStatus.fatal(message);
  }
  // is not identifier
  RefactoringStatus status = _validateIdentifier(
      identifier, desc, "an uppercase letter or underscore");
  if (!status.isOK) {
    return status;
  }
  // is private, OK
  if (identifier.codeUnitAt(0) == CHAR_UNDERSCORE) {
    return new RefactoringStatus();
  }
  // leading $, OK
  if (identifier.codeUnitAt(0) == CHAR_DOLLAR) {
    return new RefactoringStatus();
  }
  // does not start with upper case
  if (!isUpperCase(identifier.codeUnitAt(0))) {
    // By convention, class names usually start with an uppercase letter
    String message = "$desc should start with an uppercase letter.";
    return new RefactoringStatus.warning(message);
  }
  // OK
  return new RefactoringStatus();
}
