// Copyright (c) 2021, 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/refactoring/naming_conventions.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/micro/resolve_file.dart';
import 'package:analyzer/src/dart/micro/utils.dart';
import 'package:analyzer/src/utilities/extensions/collection.dart';

class CanRenameResponse {
  final LineInfo lineInfo;
  final RenameRefactoringElement refactoringElement;
  final FileResolver _fileResolver;
  final String filePath;

  FlutterWidgetState? _flutterWidgetState;

  CanRenameResponse(this.lineInfo, this.refactoringElement, this._fileResolver,
      this.filePath);

  String get oldName => refactoringElement.element.displayName;

  CheckNameResponse? checkNewName(String name) {
    var element = refactoringElement.element;
    _flutterWidgetState = _findFlutterStateClass(element, name);

    RefactoringStatus? status;
    if (element is ParameterElement) {
      status = validateParameterName(name);
    } else if (element is VariableElement) {
      status = validateVariableName(name);
    } else if (element is FunctionElement) {
      status = validateFunctionName(name);
    } else if (element is FieldElement) {
      status = validateFieldName(name);
    } else if (element is TypeAliasElement) {
      status = validateTypeAliasName(name);
    } else if (element is ClassElement) {
      status = validateClassName(name);
    }

    if (status == null) {
      return null;
    }
    return CheckNameResponse(status, this);
  }

  FlutterWidgetState? _findFlutterStateClass(Element element, String newName) {
    if (Flutter.instance.isStatefulWidgetDeclaration(element)) {
      var oldStateName = element.displayName + 'State';
      var library = element.library!;
      var state =
          library.getType(oldStateName) ?? library.getType('_' + oldStateName);
      if (state != null) {
        var flutterWidgetStateNewName = newName + 'State';
        // If the State was private, ensure that it stays private.
        if (state.name.startsWith('_') &&
            !flutterWidgetStateNewName.startsWith('_')) {
          flutterWidgetStateNewName = '_' + flutterWidgetStateNewName;
        }
        return FlutterWidgetState(state, flutterWidgetStateNewName);
      }
    }
    return null;
  }
}

class CheckNameResponse {
  final RefactoringStatus status;
  final CanRenameResponse canRename;

  CheckNameResponse(this.status, this.canRename);

  LineInfo get lineInfo => canRename.lineInfo;

  String get oldName => canRename.refactoringElement.element.displayName;

  @Deprecated('Use computeRenameRanges2() instead')
  RenameResponse? computeRenameRanges() {
    var elements = <Element>[];
    var element = canRename.refactoringElement.element;
    if (element is PropertyInducingElement && element.isSynthetic) {
      var property = element;
      var getter = property.getter;
      var setter = property.setter;
      elements.addIfNotNull(getter);
      elements.addIfNotNull(setter);
    } else {
      elements.add(element);
    }
    var matches = <CiderSearchMatch>[];
    for (var element in elements) {
      matches.addAll(canRename._fileResolver.findReferences(element));
    }
    FlutterWidgetRename? flutterRename;
    if (canRename._flutterWidgetState != null) {
      var stateWidget = canRename._flutterWidgetState!;
      var match = canRename._fileResolver.findReferences(stateWidget.state);
      flutterRename = FlutterWidgetRename(stateWidget.newName, match);
    }
    return RenameResponse(matches, this, flutterWidgetRename: flutterRename);
  }

  Future<RenameResponse?> computeRenameRanges2() async {
    // ignore: deprecated_member_use_from_same_package
    return computeRenameRanges();
  }
}

class CiderRenameComputer {
  final FileResolver _fileResolver;

  CiderRenameComputer(this._fileResolver);

  /// Check if the identifier at the [line], [column] for the file at the
  /// [filePath] can be renamed.
  @Deprecated('Use canRename2() instead')
  CanRenameResponse? canRename(String filePath, int line, int column) {
    var resolvedUnit = _fileResolver.resolve(path: filePath);
    var lineInfo = resolvedUnit.lineInfo;
    var offset = lineInfo.getOffsetOfLine(line) + column;

    var node = NodeLocator(offset).searchWithin(resolvedUnit.unit);
    var element = getElementOfNode(node);

    if (node == null || element == null) {
      return null;
    }
    if (element.source != null && element.source!.uri.isScheme('dart')) {
      return null;
    }
    if (element is MethodElement && element.isOperator) {
      return null;
    }
    if (element is PropertyAccessorElement) {
      element = element.variable;
    }
    if (!_canRenameElement(element)) {
      return null;
    }
    var refactoring = RenameRefactoring.getElementToRename(node, element);
    if (refactoring != null) {
      return CanRenameResponse(lineInfo, refactoring, _fileResolver, filePath);
    }
    return null;
  }

  /// Check if the identifier at the [line], [column] for the file at the
  /// [filePath] can be renamed.
  Future<CanRenameResponse?> canRename2(
      String filePath, int line, int column) async {
    // ignore: deprecated_member_use_from_same_package
    return canRename(filePath, line, column);
  }

  bool _canRenameElement(Element element) {
    var enclosingElement = element.enclosingElement;
    if (element is ConstructorElement) {
      return false;
    }
    if (element is LabelElement || element is LocalElement) {
      return true;
    }
    if (enclosingElement is ClassElement ||
        enclosingElement is ExtensionElement ||
        enclosingElement is CompilationUnitElement) {
      return true;
    }

    return false;
  }
}

class FlutterWidgetRename {
  final String name;
  final List<CiderSearchMatch> matches;

  FlutterWidgetRename(this.name, this.matches);
}

/// The corresponding `State` declaration of a  Flutter `StatefulWidget`.
class FlutterWidgetState {
  ClassElement state;
  String newName;

  FlutterWidgetState(this.state, this.newName);
}

class RenameResponse {
  final List<CiderSearchMatch> matches;
  final CheckNameResponse checkName;
  FlutterWidgetRename? flutterWidgetRename;

  RenameResponse(this.matches, this.checkName, {this.flutterWidgetRename});
}
