// Copyright (c) 2016, 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:kernel/ast.dart';
import 'package:kernel/core_types.dart';

import '../../base/nnbd_mode.dart';
import '../source/source_library_builder.dart';

const String lateFieldPrefix = '_#';
const String lateIsSetSuffix = '#isSet';
const String lateLocalPrefix = '#';
const String lateLocalGetterSuffix = '#get';
const String lateLocalSetterSuffix = '#set';

/// Creates the body for the synthesized getter used to encode the lowering
/// of a late non-final field or local with an initializer.
///
/// Late final fields and locals need to detect writes during initialization and
/// therefore uses [createGetterWithInitializerWithRecheck] instead.
Statement createGetterWithInitializer(CoreTypes coreTypes, int fileOffset,
    String name, DartType type, Expression initializer,
    {required Expression createVariableRead({bool needsPromotion}),
    required Expression createVariableWrite(Expression value),
    required Expression createIsSetRead(),
    required Expression createIsSetWrite(Expression value),
    required IsSetEncoding isSetEncoding}) {
  // ignore: unnecessary_null_comparison
  assert(isSetEncoding != null);
  switch (isSetEncoding) {
    case IsSetEncoding.useIsSetField:
      // Generate:
      //
      //    if (!_#isSet#field) {
      //      _#field = <init>;
      //      _#isSet#field = true
      //    }
      //    return _#field;
      return new Block(<Statement>[
        new IfStatement(
            new Not(createIsSetRead()..fileOffset = fileOffset)
              ..fileOffset = fileOffset,
            new Block(<Statement>[
              new ExpressionStatement(
                  createVariableWrite(initializer)..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
              new ExpressionStatement(
                  createIsSetWrite(
                      new BoolLiteral(true)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
            ]),
            null)
          ..fileOffset = fileOffset,
        new ReturnStatement(
            // If [type] is a type variable with undetermined nullability we
            // need to create a read of the field that is promoted to the type
            // variable type.
            createVariableRead(needsPromotion: type.isPotentiallyNonNullable))
          ..fileOffset = fileOffset
      ])
        ..fileOffset = fileOffset;
    case IsSetEncoding.useSentinel:
      // Generate:
      //
      //    return let # = _#field in isSentinel(#) ? _#field = <init> : #;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead(needsPromotion: false)..fileOffset = fileOffset,
          type: type.withDeclaredNullability(Nullability.nullable))
        ..fileOffset = fileOffset;
      return new ReturnStatement(
          new Let(
              variable,
              new ConditionalExpression(
                  new StaticInvocation(
                      coreTypes.isSentinelMethod,
                      new Arguments(<Expression>[
                        new VariableGet(variable)..fileOffset = fileOffset
                      ])
                        ..fileOffset = fileOffset)
                    ..fileOffset = fileOffset,
                  createVariableWrite(initializer)..fileOffset = fileOffset,
                  new VariableGet(variable, type)..fileOffset = fileOffset,
                  type)
                ..fileOffset = fileOffset)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
    case IsSetEncoding.useNull:
      // Generate:
      //
      //    return let # = _#field in # == null ? _#field = <init> : #;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead(needsPromotion: false)..fileOffset = fileOffset,
          type: type.withDeclaredNullability(Nullability.nullable))
        ..fileOffset = fileOffset;
      return new ReturnStatement(
          new Let(
              variable,
              new ConditionalExpression(
                  new EqualsNull(
                      new VariableGet(variable)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset,
                  createVariableWrite(initializer)..fileOffset = fileOffset,
                  new VariableGet(variable, type)..fileOffset = fileOffset,
                  type)
                ..fileOffset = fileOffset)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
  }
}

/// Creates the body for the synthesized getter used to encode the lowering
/// of a late final field or local with an initializer.
Statement createGetterWithInitializerWithRecheck(CoreTypes coreTypes,
    int fileOffset, String name, DartType type, Expression initializer,
    {required Expression createVariableRead({bool needsPromotion}),
    required Expression createVariableWrite(Expression value),
    required Expression createIsSetRead(),
    required Expression createIsSetWrite(Expression value),
    required IsSetEncoding isSetEncoding,
    required bool forField}) {
  // ignore: unnecessary_null_comparison
  assert(forField != null);
  Constructor constructor = forField
      ? coreTypes.lateInitializationFieldAssignedDuringInitializationConstructor
      : coreTypes
          .lateInitializationLocalAssignedDuringInitializationConstructor;
  Expression exception = new Throw(
      new ConstructorInvocation(
          constructor,
          new Arguments(
              <Expression>[new StringLiteral(name)..fileOffset = fileOffset])
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset)
    ..fileOffset = fileOffset;
  VariableDeclaration temp =
      new VariableDeclaration.forValue(initializer, type: type)
        ..fileOffset = fileOffset;
  switch (isSetEncoding) {
    case IsSetEncoding.useIsSetField:
      // Generate:
      //
      //    if (!_#isSet#field) {
      //      var temp = <init>;
      //      if (_#isSet#field) throw '...'
      //      _#field = temp;
      //      _#isSet#field = true
      //    }
      //    return _#field;
      return new Block(<Statement>[
        new IfStatement(
            new Not(createIsSetRead()..fileOffset = fileOffset)
              ..fileOffset = fileOffset,
            new Block(<Statement>[
              temp,
              new IfStatement(
                  createIsSetRead()..fileOffset = fileOffset,
                  new ExpressionStatement(exception)..fileOffset = fileOffset,
                  null)
                ..fileOffset = fileOffset,
              new ExpressionStatement(
                  createVariableWrite(
                      new VariableGet(temp)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
              new ExpressionStatement(
                  createIsSetWrite(
                      new BoolLiteral(true)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
            ]),
            null)
          ..fileOffset = fileOffset,
        new ReturnStatement(
            // If [type] is a type variable with undetermined nullability we
            // need to create a read of the field that is promoted to the type
            // variable type.
            createVariableRead(needsPromotion: type.isPotentiallyNonNullable))
          ..fileOffset = fileOffset
      ])
        ..fileOffset = fileOffset;
    case IsSetEncoding.useSentinel:
      // Generate:
      //
      //    return let #1 = _#field in isSentinel(#1)
      //        ? let #2 = <init> in isSentinel(_#field)
      //            ? _#field = #2 : throw '...'
      //        : #1;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead(needsPromotion: false)..fileOffset = fileOffset,
          type: type)
        ..fileOffset = fileOffset;
      return new ReturnStatement(
          new Let(
              variable,
              new ConditionalExpression(
                  new StaticInvocation(
                      coreTypes.isSentinelMethod,
                      new Arguments(<Expression>[
                        new VariableGet(variable)..fileOffset = fileOffset
                      ])
                        ..fileOffset = fileOffset)
                    ..fileOffset = fileOffset,
                  new Let(
                      temp,
                      new ConditionalExpression(
                          new StaticInvocation(
                              coreTypes.isSentinelMethod,
                              new Arguments(<Expression>[
                                createVariableRead(needsPromotion: false)
                                  ..fileOffset = fileOffset
                              ])
                                ..fileOffset = fileOffset)
                            ..fileOffset = fileOffset,
                          createVariableWrite(
                              new VariableGet(temp)..fileOffset = fileOffset)
                            ..fileOffset = fileOffset,
                          exception,
                          type)
                        ..fileOffset = fileOffset),
                  new VariableGet(variable)..fileOffset = fileOffset,
                  type)
                ..fileOffset = fileOffset)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
    case IsSetEncoding.useNull:
      // Generate:
      //
      //    return let #1 = _#field in #1 == null
      //        ? let #2 = <init> in _#field == null
      //            ? _#field = #2 : throw '...'
      //        : #1;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead(needsPromotion: false)..fileOffset = fileOffset,
          type: type.withDeclaredNullability(Nullability.nullable))
        ..fileOffset = fileOffset;
      return new ReturnStatement(
          new Let(
              variable,
              new ConditionalExpression(
                  new EqualsNull(
                      new VariableGet(variable)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset,
                  new Let(
                      temp,
                      new ConditionalExpression(
                          new EqualsNull(
                              createVariableRead(needsPromotion: false)
                                ..fileOffset = fileOffset)
                            ..fileOffset = fileOffset,
                          createVariableWrite(
                              new VariableGet(temp)..fileOffset = fileOffset)
                            ..fileOffset = fileOffset,
                          exception,
                          type)
                        ..fileOffset = fileOffset),
                  new VariableGet(variable, type)..fileOffset = fileOffset,
                  type)
                ..fileOffset = fileOffset)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
  }
}

/// Creates the body for the synthesized getter used to encode the lowering
/// of a late field or local without an initializer.
Statement createGetterBodyWithoutInitializer(
    CoreTypes coreTypes, int fileOffset, String name, DartType type,
    {required Expression createVariableRead({bool needsPromotion}),
    required Expression createIsSetRead(),
    required IsSetEncoding isSetEncoding,
    required bool forField}) {
  // ignore: unnecessary_null_comparison
  assert(forField != null);
  // ignore: unnecessary_null_comparison
  assert(isSetEncoding != null);
  Expression exception = new Throw(
      new ConstructorInvocation(
          forField
              ? coreTypes.lateInitializationFieldNotInitializedConstructor
              : coreTypes.lateInitializationLocalNotInitializedConstructor,
          new Arguments(
              <Expression>[new StringLiteral(name)..fileOffset = fileOffset])
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset)
    ..fileOffset = fileOffset;
  switch (isSetEncoding) {
    case IsSetEncoding.useIsSetField:
      // Generate:
      //
      //    return _#isSet#field ? _#field : throw '...';
      return new ReturnStatement(
          new ConditionalExpression(
              createIsSetRead()..fileOffset = fileOffset,
              createVariableRead(needsPromotion: type.isPotentiallyNonNullable)
                ..fileOffset = fileOffset,
              exception,
              type)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
    case IsSetEncoding.useSentinel:
      // Generate:
      //
      //    return let # = _#field in isSentinel(#) ? throw '...' : #;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead()..fileOffset = fileOffset,
          type: type.withDeclaredNullability(Nullability.nullable))
        ..fileOffset = fileOffset;
      return new ReturnStatement(
          new Let(
              variable,
              new ConditionalExpression(
                  new StaticInvocation(
                      coreTypes.isSentinelMethod,
                      new Arguments(<Expression>[
                        new VariableGet(variable)..fileOffset = fileOffset
                      ])
                        ..fileOffset = fileOffset)
                    ..fileOffset = fileOffset,
                  exception,
                  new VariableGet(variable, type)..fileOffset = fileOffset,
                  type)
                ..fileOffset = fileOffset)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
    case IsSetEncoding.useNull:
      // Generate:
      //
      //    return let # = _#field in # == null ? throw '...' : #;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead()..fileOffset = fileOffset,
          type: type.withDeclaredNullability(Nullability.nullable))
        ..fileOffset = fileOffset;
      return new ReturnStatement(
          new Let(
              variable,
              new ConditionalExpression(
                  new EqualsNull(
                      new VariableGet(variable)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset,
                  exception,
                  new VariableGet(variable, type)..fileOffset = fileOffset,
                  type)
                ..fileOffset = fileOffset)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
  }
}

/// Creates the body for the synthesized setter used to encode the lowering
/// of a non-final late field or local.
Statement createSetterBody(CoreTypes coreTypes, int fileOffset, String name,
    VariableDeclaration parameter, DartType type,
    {required bool shouldReturnValue,
    required Expression createVariableWrite(Expression value),
    required Expression createIsSetWrite(Expression value),
    required IsSetEncoding isSetEncoding}) {
  // ignore: unnecessary_null_comparison
  assert(isSetEncoding != null);
  Statement createReturn(Expression value) {
    if (shouldReturnValue) {
      return new ReturnStatement(value)..fileOffset = fileOffset;
    } else {
      return new ExpressionStatement(value)..fileOffset = fileOffset;
    }
  }

  Statement assignment = createReturn(
      createVariableWrite(new VariableGet(parameter)..fileOffset = fileOffset)
        ..fileOffset = fileOffset);

  switch (isSetEncoding) {
    case IsSetEncoding.useIsSetField:
      // Generate:
      //
      //    _#isSet#field = true;
      //    return _#field = parameter
      //
      return new Block([
        new ExpressionStatement(
            createIsSetWrite(new BoolLiteral(true)..fileOffset = fileOffset)
              ..fileOffset = fileOffset)
          ..fileOffset = fileOffset,
        assignment
      ])
        ..fileOffset = fileOffset;
    case IsSetEncoding.useSentinel:
    case IsSetEncoding.useNull:
      // Generate:
      //
      //    return _#field = parameter
      //
      return assignment;
  }
}

/// Creates the body for the synthesized setter used to encode the lowering
/// of a final late field or local.
Statement createSetterBodyFinal(CoreTypes coreTypes, int fileOffset,
    String name, VariableDeclaration parameter, DartType type,
    {required bool shouldReturnValue,
    required Expression createVariableRead(),
    required Expression createVariableWrite(Expression value),
    required Expression createIsSetRead(),
    required Expression createIsSetWrite(Expression value),
    required IsSetEncoding isSetEncoding,
    required bool forField}) {
  // ignore: unnecessary_null_comparison
  assert(forField != null);
  // ignore: unnecessary_null_comparison
  assert(isSetEncoding != null);
  Expression exception = new Throw(
      new ConstructorInvocation(
          forField
              ? coreTypes.lateInitializationFieldAlreadyInitializedConstructor
              : coreTypes.lateInitializationLocalAlreadyInitializedConstructor,
          new Arguments(
              <Expression>[new StringLiteral(name)..fileOffset = fileOffset])
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset)
    ..fileOffset = fileOffset;

  Statement createReturn(Expression value) {
    if (shouldReturnValue) {
      return new ReturnStatement(value)..fileOffset = fileOffset;
    } else {
      return new ExpressionStatement(value)..fileOffset = fileOffset;
    }
  }

  switch (isSetEncoding) {
    case IsSetEncoding.useIsSetField:
      // Generate:
      //
      //    if (_#isSet#field) {
      //      throw '...';
      //    } else
      //      _#isSet#field = true;
      //      return _#field = parameter
      //    }
      return new IfStatement(
          createIsSetRead()..fileOffset = fileOffset,
          new ExpressionStatement(exception)..fileOffset = fileOffset,
          new Block([
            new ExpressionStatement(
                createIsSetWrite(new BoolLiteral(true)..fileOffset = fileOffset)
                  ..fileOffset = fileOffset)
              ..fileOffset = fileOffset,
            createReturn(createVariableWrite(
                new VariableGet(parameter)..fileOffset = fileOffset)
              ..fileOffset = fileOffset)
          ])
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
    case IsSetEncoding.useSentinel:
      // Generate:
      //
      //    if (isSentinel(_#field)) {
      //      return _#field = parameter;
      //    } else {
      //      throw '...';
      //    }
      return new IfStatement(
        new StaticInvocation(
            coreTypes.isSentinelMethod,
            new Arguments(
                <Expression>[createVariableRead()..fileOffset = fileOffset])
              ..fileOffset = fileOffset)
          ..fileOffset = fileOffset,
        createReturn(createVariableWrite(
            new VariableGet(parameter)..fileOffset = fileOffset)
          ..fileOffset = fileOffset),
        new ExpressionStatement(exception)..fileOffset = fileOffset,
      )..fileOffset = fileOffset;
    case IsSetEncoding.useNull:
      // Generate:
      //
      //    if (_#field == null) {
      //      return _#field = parameter;
      //    } else {
      //      throw '...';
      //    }
      return new IfStatement(
        new EqualsNull(createVariableRead()..fileOffset = fileOffset)
          ..fileOffset = fileOffset,
        createReturn(createVariableWrite(
            new VariableGet(parameter)..fileOffset = fileOffset)
          ..fileOffset = fileOffset),
        new ExpressionStatement(exception)..fileOffset = fileOffset,
      )..fileOffset = fileOffset;
  }
}

/// Strategies for encoding whether a late field/local has been initialized.
enum IsSetEncoding {
  /// Use a boolean `isSet` field/local.
  useIsSetField,

  /// Use `null` as sentinel value to signal an uninitialized field/locals.
  useNull,

  /// Use `createSentinel`and `isSentinel` from `dart:_internal` to generate
  /// and check a sentinel value to signal an uninitialized field/local.
  useSentinel,
}

/// Strategies for encoding of late fields and locals.
enum IsSetStrategy {
  /// Always is use an `isSet` field/local to track whether the field/local has
  /// been initialized.
  forceUseIsSetField,

  /// Always use `createSentinel`and `isSentinel` from `dart:_internal` to
  /// generate and check a sentinel value to signal an uninitialized
  /// field/local.
  forceUseSentinel,

  /// For potentially nullable fields/locals use an `isSet` field/local to track
  /// whether the field/local has been initialized. Otherwise use `null` as
  /// sentinel value to signal an uninitialized field/local.
  ///
  /// This strategy can only be used with sound null safety mode. In weak mode
  /// non-nullable can be assigned `null` from legacy code and therefore `null`
  /// doesn't work as a sentinel.
  useIsSetFieldOrNull,

  /// For potentially nullable fields/locals use `createSentinel`and
  /// `isSentinel` from `dart:_internal` to generate and check a sentinel value
  /// to signal an uninitialized field/local. Otherwise use `null` as
  /// sentinel value to signal an uninitialized field/local.
  useSentinelOrNull,
}

IsSetStrategy computeIsSetStrategy(SourceLibraryBuilder libraryBuilder) {
  IsSetStrategy isSetStrategy = IsSetStrategy.useIsSetFieldOrNull;
  if (libraryBuilder.loader.target.backendTarget.supportsLateLoweringSentinel) {
    if (libraryBuilder.loader.nnbdMode != NnbdMode.Strong) {
      // Non-nullable fields/locals might contain `null` so we always use the
      // sentinel.
      isSetStrategy = IsSetStrategy.forceUseSentinel;
    } else {
      isSetStrategy = IsSetStrategy.useSentinelOrNull;
    }
  } else if (libraryBuilder.loader.nnbdMode != NnbdMode.Strong) {
    isSetStrategy = IsSetStrategy.forceUseIsSetField;
  }
  return isSetStrategy;
}

IsSetEncoding computeIsSetEncoding(DartType type, IsSetStrategy isSetStrategy) {
  switch (isSetStrategy) {
    case IsSetStrategy.forceUseIsSetField:
      return IsSetEncoding.useIsSetField;
    case IsSetStrategy.forceUseSentinel:
      return IsSetEncoding.useSentinel;
    case IsSetStrategy.useIsSetFieldOrNull:
      return type.isPotentiallyNullable
          ? IsSetEncoding.useIsSetField
          : IsSetEncoding.useNull;
    case IsSetStrategy.useSentinelOrNull:
      return type.isPotentiallyNullable
          ? IsSetEncoding.useSentinel
          : IsSetEncoding.useNull;
  }
}

/// Returns the name used for the variable that holds the value of a late
/// lowered local by the given [name].
String computeLateLocalName(String name) {
  return '${lateLocalPrefix}$name';
}

/// Returns the name used for the 'isSet' variable of a late lowered local by
/// the given [name].
String computeLateLocalIsSetName(String name) {
  return '${lateLocalPrefix}${name}${lateIsSetSuffix}';
}

/// Returns the name used for the getter function of a late lowered local by
/// the given [name].
String computeLateLocalGetterName(String name) {
  return '${lateLocalPrefix}${name}${lateLocalGetterSuffix}';
}

/// Returns the name used for the setter function of a late lowered local by
/// the given [name].
String computeLateLocalSetterName(String name) {
  return '${lateLocalPrefix}${name}${lateLocalSetterSuffix}';
}
