// 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';
import 'package:meta/meta.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 [leaveClassOrMixin] 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) {
    _isInNativeClass = node.nativeClause != null;
    _initFieldsMap(node.declaredElement);
  }

  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) {
      return;
    }

    if (_isInNativeClass) {
      return;
    }

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

    _updateWithParameters(node);
    _updateWithInitializers(node);

    if (_hasRedirectingConstructorInvocation) {
      return;
    }

    // Prepare lists of not initialized fields.
    List<FieldElement> notInitFinalFields = <FieldElement>[];
    List<FieldElement> 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.isFinal) {
        notInitFinalFields.add(field);
      } else if (_typeSystem.isNonNullableByDefault &&
          _typeSystem.isPotentiallyNonNullable(field.type)) {
        notInitNonNullableFields.add(field);
      }
    });

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

  void _initFieldsMap(ClassElement element) {
    _initialFieldMap = <FieldElement, _InitState>{};
    for (var field in element.fields) {
      if (!field.isSynthetic) {
        _initialFieldMap[field] = field.hasInitializer
            ? _InitState.initInDeclaration
            : _InitState.notInit;
      }
    }
  }

  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;
        Element element = fieldName.staticElement;
        if (element is FieldElement) {
          _InitState 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) {
        FieldElement fieldElement =
            (parameter.declaredElement as FieldFormalParameterElementImpl)
                .field;
        _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) {
          if (fieldElement.isFinal || fieldElement.isConst) {
            _errorReporter.reportErrorForNode(
              CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES,
              parameter.identifier,
              [fieldElement.displayName],
            );
          }
        }
      }
    }
  }

  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,
}
