// Copyright (c) 2019, 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:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/summary2/link.dart';

class TypeAliasSelfReferenceFinder {
  /// Check typedefs and mark the ones having self references.
  void perform(Linker linker) {
    for (var builder in linker.builders.values) {
      for (var linkingUnit in builder.units) {
        for (var node in linkingUnit.node.declarations) {
          if (node is FunctionTypeAlias) {
            var finder = _Finder(linker, node);
            finder.functionTypeAlias(node);
            var element = node.declaredElement as TypeAliasElementImpl;
            element.hasSelfReference = finder.hasSelfReference;
          } else if (node is GenericTypeAlias) {
            var finder = _Finder(linker, node);
            finder.genericTypeAlias(node);
            var element = node.declaredElement as TypeAliasElementImpl;
            element.hasSelfReference = finder.hasSelfReference;
          }
        }
      }
    }
  }
}

class _Finder {
  final Linker linker;
  final AstNode self;
  final Set<AstNode> visited = Set.identity();
  bool hasSelfReference = false;

  _Finder(this.linker, this.self);

  void functionTypeAlias(FunctionTypeAlias node) {
    _typeParameterList(node.typeParameters);
    _formalParameterList(node.parameters);
    _visit(node.returnType);
  }

  void genericTypeAlias(GenericTypeAlias node) {
    _typeParameterList(node.typeParameters);
    _visit(node.type);
  }

  void _argumentList(TypeArgumentList? node) {
    if (node != null) {
      for (var argument in node.arguments) {
        _visit(argument);
      }
    }
  }

  void _formalParameter(FormalParameter node) {
    if (node is DefaultFormalParameter) {
      _formalParameter(node.parameter);
    } else if (node is FunctionTypedFormalParameter) {
      _visit(node.returnType);
      _formalParameterList(node.parameters);
    } else if (node is SimpleFormalParameter) {
      _visit(node.type);
    }
  }

  void _formalParameterList(FormalParameterList node) {
    for (var parameter in node.parameters) {
      _formalParameter(parameter);
    }
  }

  void _typeParameterList(TypeParameterList? node) {
    if (node != null) {
      for (var parameter in node.typeParameters) {
        _visit(parameter.bound);
      }
    }
  }

  void _visit(TypeAnnotation? node) {
    if (hasSelfReference) return;
    if (node == null) return;

    if (node is TypeName) {
      var element = node.name.staticElement;
      if (element is! ElementImpl) {
        return;
      }

      var typeNode = linker.getLinkingNode(element);
      if (typeNode != null) {
        if (typeNode == self) {
          hasSelfReference = true;
          return;
        }
        if (typeNode is ClassDeclaration) {
          if (visited.add(typeNode)) {
            _typeParameterList(typeNode.typeParameters);
          }
        } else if (typeNode is ClassTypeAlias) {
          if (visited.add(typeNode)) {
            _typeParameterList(typeNode.typeParameters);
          }
        } else if (typeNode is FunctionTypeAlias) {
          if (visited.add(typeNode)) {
            functionTypeAlias(typeNode);
          }
        } else if (typeNode is GenericTypeAlias) {
          if (visited.add(typeNode)) {
            genericTypeAlias(typeNode);
          }
        } else if (typeNode is MixinDeclaration) {
          if (visited.add(typeNode)) {
            _typeParameterList(typeNode.typeParameters);
          }
        }
      }
      _argumentList(node.typeArguments);
    } else if (node is GenericFunctionType) {
      _typeParameterList(node.typeParameters);
      _formalParameterList(node.parameters);
      _visit(node.returnType);
    } else {
      throw UnimplementedError('(${node.runtimeType}) $node');
    }
  }
}
