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

/// 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.isEmpty) {
    return RefactoringStatus();
  }
  return _validateLowerCamelCase(name, 'Constructor', allowBuiltIn: true);
}

/// 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', allowBuiltIn: true);
}

/// 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', allowBuiltIn: true);
}

/// 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.isEmpty) {
    return 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', allowBuiltIn: true);
}

/// 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) {
  // blank
  if (isBlank(name)) {
    return RefactoringStatus.fatal('Library name must not be blank.');
  }
  // check identifiers
  var identifiers = name.split('.');
  for (var identifier in identifiers) {
    var status = _validateIdentifier(identifier, 'Library name identifier',
        'a lowercase letter or underscore');
    if (!status.isOK) {
      return status;
    }
  }
  // should not have upper-case letters
  for (var identifier in identifiers) {
    for (var c in identifier.codeUnits) {
      if (isUpperCase(c)) {
        return RefactoringStatus.warning(
            'Library name should consist of lowercase identifier separated by dots.');
      }
    }
  }
  // OK
  return 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', allowBuiltIn: true);
}

/// 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', allowBuiltIn: true);
}

/// Returns the [RefactoringStatus] with severity:
/// - OK if the name is valid;
/// - WARNING if the name is discouraged;
/// - FATAL if the name is illegal.
RefactoringStatus validateTypeAliasName(String name) {
  return _validateUpperCamelCase(name, '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 validateVariableName(String name) {
  return _validateLowerCamelCase(name, 'Variable', allowBuiltIn: true);
}

RefactoringStatus _validateIdentifier(
    String identifier, String desc, String beginDesc,
    {bool allowBuiltIn = false}) {
  // has leading/trailing spaces
  var trimmed = identifier.trim();
  if (identifier != trimmed) {
    var message = '$desc must not start or end with a blank.';
    return RefactoringStatus.fatal(message);
  }
  // empty
  var length = identifier.length;
  if (length == 0) {
    var message = '$desc must not be empty.';
    return RefactoringStatus.fatal(message);
  }
  // keyword
  {
    var keyword = Keyword.keywords[identifier];
    if (keyword != null) {
      if (keyword.isBuiltInOrPseudo && allowBuiltIn) {
        var message = 'Avoid using built-in identifiers as names.';
        return RefactoringStatus.warning(message);
      } else {
        var message = '$desc must not be a keyword.';
        return RefactoringStatus.fatal(message);
      }
    }
  }
  // invalid characters
  for (var i = 0; i < length; i++) {
    var currentChar = identifier.codeUnitAt(i);
    if (!isLetterOrDigit(currentChar) &&
        currentChar != CHAR_UNDERSCORE &&
        currentChar != CHAR_DOLLAR) {
      var charStr = String.fromCharCode(currentChar);
      var message = "$desc must not contain '$charStr'.";
      return RefactoringStatus.fatal(message);
    }
  }
  // first character
  var currentChar = identifier.codeUnitAt(0);
  if (!isLetter(currentChar) &&
      currentChar != CHAR_UNDERSCORE &&
      currentChar != CHAR_DOLLAR) {
    var message = '$desc must begin with $beginDesc.';
    return RefactoringStatus.fatal(message);
  }
  // OK
  return RefactoringStatus();
}

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

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