// 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 unitContext in builder.context.units) {
        for (var node in unitContext.unit.declarations) {
          if (node is FunctionTypeAlias) {
            var finder = _Finder(node);
            finder.functionTypeAlias(node);
            var element = node.declaredElement as TypeAliasElementImpl;
            element.hasSelfReference = finder.hasSelfReference;
          } else if (node is GenericTypeAlias) {
            var finder = _Finder(node);
            finder.genericTypeAlias(node);
            var element = node.declaredElement as TypeAliasElementImpl;
            element.hasSelfReference = finder.hasSelfReference;
          }
        }
      }
    }
  }
}

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

  _Finder(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;
      // TODO(scheglov) We have `linkedContext` only during linking.
      if (element is ElementImpl &&
          element.enclosingElement != null &&
          element.linkedContext != null &&
          element.linkedContext!.isLinking) {
        var typeNode = element.linkedNode;
        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');
    }
  }
}
