// Copyright (c) 2020, 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/fix/data_driven/parameter_reference.dart';
import 'package:analyzer/dart/ast/ast.dart';

/// A class that can be used to access a value from a target.
abstract class Accessor {
  /// Return the result of using this accessor to access a value from the
  /// [target].
  AccessorResult getValue(Object target);
}

/// The result of using an accessor to get a result.
abstract class AccessorResult {
  /// Initialize a newly created result.
  const AccessorResult();

  /// Return `true` if the accessor returned a valid result.
  bool get isValid;

  /// Return the result of the accessor if it was valid.
  ///
  /// Throws a `StateError` if the accessor did not return a valid result.
  Object get result;
}

/// An accessor that returns a specific argument from an argument list.
class ArgumentAccessor extends Accessor {
  /// The parameter corresponding to the argument from the original invocation.
  final ParameterReference parameter;

  /// Initialize a newly created accessor to access the argument that
  /// corresponds to the given [parameter].
  ArgumentAccessor(this.parameter) : assert(parameter != null);

  @override
  AccessorResult getValue(Object target) {
    if (target is AstNode) {
      var argumentList = _getArgumentList(target);
      if (argumentList != null) {
        var argument = parameter.argumentFrom(argumentList);
        if (argument != null) {
          return ValidResult(argument);
        }
      }
    }
    return const InvalidResult();
  }

  @override
  String toString() => 'arguments[$parameter]';

  /// Return the argument list associated with the [node].
  ArgumentList _getArgumentList(AstNode node) {
    if (node is Annotation) {
      return node.arguments;
    } else if (node is ExtensionOverride) {
      return node.argumentList;
    } else if (node is InstanceCreationExpression) {
      return node.argumentList;
    } else if (node is InvocationExpression) {
      return node.argumentList;
    } else if (node is RedirectingConstructorInvocation) {
      return node.argumentList;
    } else if (node is SuperConstructorInvocation) {
      return node.argumentList;
    }
    return null;
  }
}

/// A representation of an invalid result.
class InvalidResult implements AccessorResult {
  /// Initialize a newly created invalid result.
  const InvalidResult();

  @override
  bool get isValid => false;

  @override
  Object get result => throw StateError('Cannot access an invalid result');
}

/// An accessor that returns a specific type argument from a type argument list.
class TypeArgumentAccessor extends Accessor {
  /// The index of the type argument.
  final int index;

  /// Initialize a newly created accessor to access the type argument at the
  /// given [index].
  TypeArgumentAccessor(this.index) : assert(index != null);

  @override
  AccessorResult getValue(Object target) {
    if (target is AstNode) {
      var typeArgumentList = _getTypeArgumentList(target);
      if (typeArgumentList != null) {
        var arguments = typeArgumentList.arguments;
        if (arguments.length > index) {
          var argument = arguments[index];
          if (argument != null) {
            return ValidResult(argument);
          }
        }
      }
    }
    return const InvalidResult();
  }

  @override
  String toString() => 'typeArguments[$index]';

  /// Return the type argument list associated with the [node].
  TypeArgumentList _getTypeArgumentList(AstNode node) {
    if (node is ExtensionOverride) {
      return node.typeArguments;
    } else if (node is InstanceCreationExpression) {
      return node.constructorName.type.typeArguments;
    } else if (node is InvocationExpression) {
      return node.typeArguments;
    } else if (node is NamedType) {
      return node.typeArguments;
    } else if (node is TypedLiteral) {
      return node.typeArguments;
    }
    return null;
  }
}

/// A representation of a valid result.
class ValidResult implements AccessorResult {
  @override
  final Object result;

  /// Initialize a newly created valid result.
  ValidResult(this.result);

  @override
  bool get isValid => true;
}
