// 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/dart/element/element.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/error/codes.dart';

/// Verifier for initializing fields in constructors.
class ConstructorFieldsVerifier {
  final TypeSystemImpl _typeSystem;
  final ErrorReporter _errorReporter;

  bool _isInNativeClass = false;

  /// When a new class or mixin is entered, [_initFieldsMap] initializes this
  /// map, and [leaveClass] resets it.
  ///
  /// [_InitState.notInit] or [_InitState.initInDeclaration] is set for each
  /// field. Later [verify] is called to verify each constructor of the class.
  Map<FieldElement, _InitState>? _initialFieldMap;

  /// The state of fields in the current constructor.
  Map<FieldElement, _InitState> _fieldMap = {};

  /// Set to `true` if the current constructor redirects.
  bool _hasRedirectingConstructorInvocation = false;

  ConstructorFieldsVerifier({
    required TypeSystemImpl typeSystem,
    required ErrorReporter errorReporter,
  })  : _typeSystem = typeSystem,
        _errorReporter = errorReporter;

  void enterClass(ClassDeclaration node, ClassElementImpl element) {
    _isInNativeClass = node.nativeClause != null;
    _initFieldsMap(element.fields);
  }

  void enterEnum(EnumDeclaration node, EnumElementImpl element) {
    _isInNativeClass = false;
    _initFieldsMap(
      element.fields,
      enumConstants: element.constants,
    );
  }

  void leaveClass() {
    _isInNativeClass = false;
    _initialFieldMap = null;
  }

  /// Verify that the given [node] declaration does not violate any of
  /// the error codes relating to the initialization of fields in the
  /// enclosing class.
  void verify(ConstructorDeclaration node) {
    if (node.factoryKeyword != null ||
        node.redirectedConstructor != null ||
        node.externalKeyword != null) {
      return;
    }

    if (!(node.parent is ClassDeclaration || node.parent is EnumDeclaration)) {
      return;
    }

    if (_isInNativeClass) {
      return;
    }

    _fieldMap = Map.of(_initialFieldMap!);
    _hasRedirectingConstructorInvocation = false;

    _updateWithParameters(node);
    _updateWithInitializers(node);

    if (_hasRedirectingConstructorInvocation) {
      return;
    }

    // Prepare lists of not initialized fields.
    var notInitFinalFields = <FieldElement>[];
    var notInitNonNullableFields = <FieldElement>[];
    _fieldMap.forEach((FieldElement field, _InitState state) {
      if (state != _InitState.notInit) return;
      if (field.isLate) return;
      if (field.isAbstract || field.isExternal) return;
      if (field.isStatic) return;

      if (field.isFinal) {
        notInitFinalFields.add(field);
      } else if (_typeSystem.isNonNullableByDefault &&
          _typeSystem.isPotentiallyNonNullable(field.type)) {
        notInitNonNullableFields.add(field);
      }
    });

    _reportNotInitializedFinal(node, notInitFinalFields);
    _reportNotInitializedNonNullable(node, notInitNonNullableFields);
  }

  void _initFieldsMap(
    List<FieldElement> fields, {
    List<FieldElement>? enumConstants,
  }) {
    _initialFieldMap = <FieldElement, _InitState>{};

    for (var field in fields) {
      if (field.isSynthetic) {
        continue;
      }
      if (enumConstants != null && field.name == 'index') {
        continue;
      }
      _initialFieldMap![field] = field.hasInitializer
          ? _InitState.initInDeclaration
          : _InitState.notInit;
    }

    if (enumConstants != null) {
      for (var field in enumConstants) {
        _initialFieldMap![field] = _InitState.initInDeclaration;
      }
    }
  }

  void _reportNotInitializedFinal(
    ConstructorDeclaration node,
    List<FieldElement> notInitFinalFields,
  ) {
    if (notInitFinalFields.isEmpty) {
      return;
    }

    var names = notInitFinalFields.map((item) => item.name).toList();
    names.sort();

    if (names.length == 1) {
      _errorReporter.reportErrorForNode(
        CompileTimeErrorCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1,
        node.returnType,
        names,
      );
    } else if (names.length == 2) {
      _errorReporter.reportErrorForNode(
        CompileTimeErrorCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2,
        node.returnType,
        names,
      );
    } else {
      _errorReporter.reportErrorForNode(
        CompileTimeErrorCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS,
        node.returnType,
        [names[0], names[1], names.length - 2],
      );
    }
  }

  void _reportNotInitializedNonNullable(
    ConstructorDeclaration node,
    List<FieldElement> notInitNonNullableFields,
  ) {
    if (notInitNonNullableFields.isEmpty) {
      return;
    }

    var names = notInitNonNullableFields.map((f) => f.name).toList();
    names.sort();

    for (var name in names) {
      _errorReporter.reportErrorForNode(
        CompileTimeErrorCode
            .NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD_CONSTRUCTOR,
        node.returnType,
        [name],
      );
    }
  }

  void _updateWithInitializers(ConstructorDeclaration node) {
    for (var initializer in node.initializers) {
      if (initializer is RedirectingConstructorInvocation) {
        _hasRedirectingConstructorInvocation = true;
      }
      if (initializer is ConstructorFieldInitializer) {
        SimpleIdentifier fieldName = initializer.fieldName;
        var element = fieldName.staticElement;
        if (element is FieldElement) {
          var state = _fieldMap[element];
          if (state == _InitState.notInit) {
            _fieldMap[element] = _InitState.initInInitializer;
          } else if (state == _InitState.initInDeclaration) {
            if (element.isFinal || element.isConst) {
              _errorReporter.reportErrorForNode(
                CompileTimeErrorCode
                    .FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION,
                fieldName,
              );
            }
          } else if (state == _InitState.initInFieldFormal) {
            _errorReporter.reportErrorForNode(
              CompileTimeErrorCode
                  .FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER,
              fieldName,
            );
          } else if (state == _InitState.initInInitializer) {
            _errorReporter.reportErrorForNode(
              CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
              fieldName,
              [element.displayName],
            );
          }
        }
      }
    }
  }

  void _updateWithParameters(ConstructorDeclaration node) {
    var formalParameters = node.parameters.parameters;
    for (FormalParameter parameter in formalParameters) {
      parameter = _baseParameter(parameter);
      if (parameter is FieldFormalParameter) {
        var fieldElement =
            (parameter.declaredElement as FieldFormalParameterElementImpl)
                .field;
        if (fieldElement == null) {
          continue;
        }
        _InitState? state = _fieldMap[fieldElement];
        if (state == _InitState.notInit) {
          _fieldMap[fieldElement] = _InitState.initInFieldFormal;
        } else if (state == _InitState.initInDeclaration) {
          if (fieldElement.isFinal || fieldElement.isConst) {
            _errorReporter.reportErrorForNode(
              CompileTimeErrorCode
                  .FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR,
              parameter.identifier,
              [fieldElement.displayName],
            );
          }
        } else if (state == _InitState.initInFieldFormal) {
          // Reported in DuplicateDefinitionVerifier._checkDuplicateIdentifier
        }
      }
    }
  }

  static FormalParameter _baseParameter(FormalParameter parameter) {
    if (parameter is DefaultFormalParameter) {
      return parameter.parameter;
    }
    return parameter;
  }
}

/// The four states of a field initialization state through a constructor
/// signature, not initialized, initialized in the field declaration,
/// initialized in the field formal, and finally, initialized in the
/// initializers list.
enum _InitState {
  /// The field is declared without an initializer.
  notInit,

  /// The field is declared with an initializer.
  initInDeclaration,

  /// The field is initialized in a field formal parameter of the constructor
  /// being verified.
  initInFieldFormal,

  /// The field is initialized in the list of initializers of the constructor
  /// being verified.
  initInInitializer,
}
