// 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/organize_imports.dart';
import 'package:analysis_server/src/utilities/extensions/range_factory.dart';
import 'package:analysis_server/src/utilities/strings.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
import 'package:analyzer_plugin/utilities/range_factory.dart';

/// Sorter for unit/class members.
class MemberSorter {
  static final List<_PriorityItem> _PRIORITY_ITEMS = [
    _PriorityItem(false, _MemberKind.UNIT_FUNCTION_MAIN, false),
    _PriorityItem(false, _MemberKind.UNIT_VARIABLE_CONST, false),
    _PriorityItem(false, _MemberKind.UNIT_VARIABLE_CONST, true),
    _PriorityItem(false, _MemberKind.UNIT_VARIABLE, false),
    _PriorityItem(false, _MemberKind.UNIT_VARIABLE, true),
    _PriorityItem(false, _MemberKind.UNIT_ACCESSOR, false),
    _PriorityItem(false, _MemberKind.UNIT_ACCESSOR, true),
    _PriorityItem(false, _MemberKind.UNIT_FUNCTION, false),
    _PriorityItem(false, _MemberKind.UNIT_FUNCTION, true),
    _PriorityItem(false, _MemberKind.UNIT_GENERIC_TYPE_ALIAS, false),
    _PriorityItem(false, _MemberKind.UNIT_GENERIC_TYPE_ALIAS, true),
    _PriorityItem(false, _MemberKind.UNIT_FUNCTION_TYPE, false),
    _PriorityItem(false, _MemberKind.UNIT_FUNCTION_TYPE, true),
    _PriorityItem(false, _MemberKind.UNIT_CLASS, false),
    _PriorityItem(false, _MemberKind.UNIT_CLASS, true),
    _PriorityItem(false, _MemberKind.UNIT_EXTENSION, false),
    _PriorityItem(false, _MemberKind.UNIT_EXTENSION, true),
    _PriorityItem(true, _MemberKind.CLASS_FIELD, false),
    _PriorityItem(true, _MemberKind.CLASS_ACCESSOR, false),
    _PriorityItem(true, _MemberKind.CLASS_ACCESSOR, true),
    _PriorityItem(false, _MemberKind.CLASS_FIELD, false),
    _PriorityItem(false, _MemberKind.CLASS_CONSTRUCTOR, false),
    _PriorityItem(false, _MemberKind.CLASS_CONSTRUCTOR, true),
    _PriorityItem(false, _MemberKind.CLASS_ACCESSOR, false),
    _PriorityItem(false, _MemberKind.CLASS_ACCESSOR, true),
    _PriorityItem(false, _MemberKind.CLASS_METHOD, false),
    _PriorityItem(false, _MemberKind.CLASS_METHOD, true),
    _PriorityItem(true, _MemberKind.CLASS_METHOD, false),
    _PriorityItem(true, _MemberKind.CLASS_METHOD, true)
  ];

  final String initialCode;

  final CompilationUnit unit;

  final LineInfo lineInfo;

  String code;

  String endOfLine = '\n';

  MemberSorter(this.initialCode, this.unit, this.lineInfo)
      : code = initialCode {
    endOfLine = getEOL(code);
  }

  /// Return the [SourceEdit]s that sort [unit].
  List<SourceEdit> sort() {
    _sortClassesMembers();
    _sortUnitMembers();
    // Must sort unit directives last because it may insert newlines, which
    // would confuse the offsets used by the other sort functions.
    _sortUnitDirectives();
    // prepare edits
    var edits = <SourceEdit>[];
    if (code != initialCode) {
      var diff = computeSimpleDiff(initialCode, code);
      var edit = SourceEdit(diff.offset, diff.length, diff.replacement);
      edits.add(edit);
    }
    return edits;
  }

  void _sortAndReorderMembers(List<_MemberInfo> members) {
    var membersSorted = _getSortedMembers(members);
    var size = membersSorted.length;
    for (var i = 0; i < size; i++) {
      var newInfo = membersSorted[size - 1 - i];
      var oldInfo = members[size - 1 - i];
      if (newInfo != oldInfo) {
        var beforeCode = code.substring(0, oldInfo.offset);
        var afterCode = code.substring(oldInfo.end);
        code = beforeCode + newInfo.text + afterCode;
      }
    }
  }

  /// Sorts all members of all [ClassOrMixinDeclaration]s.
  void _sortClassesMembers() {
    for (var unitMember in unit.declarations) {
      if (unitMember is ClassOrMixinDeclaration) {
        _sortClassMembers(unitMember.members);
      } else if (unitMember is EnumDeclaration) {
        _sortClassMembers(unitMember.members);
      } else if (unitMember is ExtensionDeclaration) {
        _sortClassMembers(unitMember.members);
      }
    }
  }

  /// Sorts all members of the given [classDeclaration].
  void _sortClassMembers(List<ClassMember> membersToSort) {
    var members = <_MemberInfo>[];
    for (var member in membersToSort) {
      _MemberKind kind;
      var isStatic = false;
      String name;
      if (member is ConstructorDeclaration) {
        kind = _MemberKind.CLASS_CONSTRUCTOR;
        var nameNode = member.name;
        if (nameNode == null) {
          name = '';
        } else {
          name = nameNode.name;
        }
      } else if (member is FieldDeclaration) {
        var fieldDeclaration = member;
        List<VariableDeclaration> fields = fieldDeclaration.fields.variables;
        if (fields.isNotEmpty) {
          kind = _MemberKind.CLASS_FIELD;
          isStatic = fieldDeclaration.isStatic;
          name = fields[0].name.name;
        } else {
          // Don't sort members if there are errors in the code.
          return;
        }
      } else if (member is MethodDeclaration) {
        var method = member;
        isStatic = method.isStatic;
        name = method.name.name;
        if (method.isGetter) {
          kind = _MemberKind.CLASS_ACCESSOR;
          name += ' getter';
        } else if (method.isSetter) {
          kind = _MemberKind.CLASS_ACCESSOR;
          name += ' setter';
        } else {
          kind = _MemberKind.CLASS_METHOD;
        }
      } else {
        throw StateError('Unsupported class of member: ${member.runtimeType}');
      }
      var item = _PriorityItem.forName(isStatic, name, kind);
      var nodeRange = range.nodeWithComments(lineInfo, member);
      var offset = nodeRange.offset;
      var length = nodeRange.length;
      var text = code.substring(offset, offset + length);
      members.add(_MemberInfo(item, name, offset, length, text));
    }
    // do sort
    _sortAndReorderMembers(members);
  }

  /// Sorts all [Directive]s.
  void _sortUnitDirectives() {
    final importOrganizer =
        ImportOrganizer(code, unit, [], removeUnused: false);
    importOrganizer.organize();
    code = importOrganizer.code;
  }

  /// Sorts all [CompilationUnitMember]s.
  void _sortUnitMembers() {
    var members = <_MemberInfo>[];
    for (var member in unit.declarations) {
      _MemberKind kind;
      String name;
      if (member is ClassOrMixinDeclaration) {
        kind = _MemberKind.UNIT_CLASS;
        name = member.name.name;
      } else if (member is ClassTypeAlias) {
        kind = _MemberKind.UNIT_CLASS;
        name = member.name.name;
      } else if (member is EnumDeclaration) {
        kind = _MemberKind.UNIT_CLASS;
        name = member.name.name;
      } else if (member is ExtensionDeclaration) {
        kind = _MemberKind.UNIT_EXTENSION;
        name = member.name?.name ?? '';
      } else if (member is FunctionDeclaration) {
        var function = member;
        name = function.name.name;
        if (function.isGetter) {
          kind = _MemberKind.UNIT_ACCESSOR;
          name += ' getter';
        } else if (function.isSetter) {
          kind = _MemberKind.UNIT_ACCESSOR;
          name += ' setter';
        } else {
          if (name == 'main') {
            kind = _MemberKind.UNIT_FUNCTION_MAIN;
          } else {
            kind = _MemberKind.UNIT_FUNCTION;
          }
        }
      } else if (member is FunctionTypeAlias) {
        kind = _MemberKind.UNIT_FUNCTION_TYPE;
        name = member.name.name;
      } else if (member is GenericTypeAlias) {
        kind = _MemberKind.UNIT_GENERIC_TYPE_ALIAS;
        name = member.name.name;
      } else if (member is TopLevelVariableDeclaration) {
        var variableDeclaration = member;
        List<VariableDeclaration> variables =
            variableDeclaration.variables.variables;
        if (variables.isNotEmpty) {
          if (variableDeclaration.variables.isConst) {
            kind = _MemberKind.UNIT_VARIABLE_CONST;
          } else {
            kind = _MemberKind.UNIT_VARIABLE;
          }
          name = variables[0].name.name;
        } else {
          // Don't sort members if there are errors in the code.
          return;
        }
      } else {
        throw StateError('Unsupported class of member: ${member.runtimeType}');
      }
      var item = _PriorityItem.forName(false, name, kind);
      var nodeRange = range.nodeWithComments(lineInfo, member);
      var offset = nodeRange.offset;
      var length = nodeRange.length;
      var text = code.substring(offset, offset + length);
      members.add(_MemberInfo(item, name, offset, length, text));
    }
    // do sort
    _sortAndReorderMembers(members);
  }

  /// Return the EOL to use for [code].
  static String getEOL(String code) {
    if (code.contains('\r\n')) {
      return '\r\n';
    } else {
      return '\n';
    }
  }

  static int _getPriority(_PriorityItem item) {
    for (var i = 0; i < _PRIORITY_ITEMS.length; i++) {
      if (_PRIORITY_ITEMS[i] == item) {
        return i;
      }
    }
    return 0;
  }

  static List<_MemberInfo> _getSortedMembers(List<_MemberInfo> members) {
    var membersSorted = List<_MemberInfo>.from(members);
    membersSorted.sort((_MemberInfo o1, _MemberInfo o2) {
      var priority1 = _getPriority(o1.item);
      var priority2 = _getPriority(o2.item);
      if (priority1 == priority2) {
        // don't reorder class fields
        if (o1.item.kind == _MemberKind.CLASS_FIELD) {
          return o1.offset - o2.offset;
        }
        // sort all other members by name
        var name1 = o1.name.toLowerCase();
        var name2 = o2.name.toLowerCase();
        return name1.compareTo(name2);
      }
      return priority1 - priority2;
    });
    return membersSorted;
  }
}

class _MemberInfo {
  final _PriorityItem item;
  final String name;
  final int offset;
  final int length;
  final int end;
  final String text;

  _MemberInfo(this.item, this.name, this.offset, this.length, this.text)
      : end = offset + length;

  @override
  String toString() {
    return '(priority=$item; name=$name; offset=$offset; length=$length)';
  }
}

class _MemberKind {
  static const CLASS_ACCESSOR = _MemberKind('CLASS_ACCESSOR');
  static const CLASS_CONSTRUCTOR = _MemberKind('CLASS_CONSTRUCTOR');
  static const CLASS_FIELD = _MemberKind('CLASS_FIELD');
  static const CLASS_METHOD = _MemberKind('CLASS_METHOD');
  static const UNIT_ACCESSOR = _MemberKind('UNIT_ACCESSOR');
  static const UNIT_CLASS = _MemberKind('UNIT_CLASS');
  static const UNIT_EXTENSION = _MemberKind('UNIT_EXTENSION');
  static const UNIT_FUNCTION = _MemberKind('UNIT_FUNCTION');
  static const UNIT_FUNCTION_MAIN = _MemberKind('UNIT_FUNCTION_MAIN');
  static const UNIT_FUNCTION_TYPE = _MemberKind('UNIT_FUNCTION_TYPE');
  static const UNIT_GENERIC_TYPE_ALIAS = _MemberKind('UNIT_GENERIC_TYPE_ALIAS');
  static const UNIT_VARIABLE = _MemberKind('UNIT_VARIABLE');
  static const UNIT_VARIABLE_CONST = _MemberKind('UNIT_VARIABLE_CONST');

  final String name;

  const _MemberKind(this.name);

  @override
  String toString() => name;
}

class _PriorityItem {
  final _MemberKind kind;
  final bool isPrivate;
  final bool isStatic;

  _PriorityItem(this.isStatic, this.kind, this.isPrivate);

  factory _PriorityItem.forName(bool isStatic, String name, _MemberKind kind) {
    var isPrivate = Identifier.isPrivateName(name);
    return _PriorityItem(isStatic, kind, isPrivate);
  }

  @override
  bool operator ==(Object obj) {
    var other = obj as _PriorityItem;
    if (kind == _MemberKind.CLASS_FIELD) {
      return other.kind == kind && other.isStatic == isStatic;
    }
    return other.kind == kind &&
        other.isPrivate == isPrivate &&
        other.isStatic == isStatic;
  }

  @override
  String toString() => kind.toString();
}
