// 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' hide MapEntry;
import 'package:kernel/core_types.dart';
import 'package:kernel/src/future_or.dart';

import '../names.dart';

/// Creates the body for the synthesized getter used to encode the lowering
/// of a late non-final field with an initializer or a late local with an
/// initializer.
///
/// Late final field needs to detect writes during initialization and therefore
/// uses [createGetterWithInitializerWithRecheck] instead. Late final locals
/// cannot have writes during initialization since they are not in scope in
/// their own initializer.
Statement createGetterWithInitializer(CoreTypes coreTypes, int fileOffset,
    String name, DartType type, Expression initializer,
    {Expression createVariableRead({bool needsPromotion}),
    Expression createVariableWrite(Expression value),
    Expression createIsSetRead(),
    Expression createIsSetWrite(Expression value)}) {
  if (isPotentiallyNullable(type, coreTypes.futureOrClass)) {
    // Generate:
    //
    //    if (!_#isSet#field) {
    //      _#isSet#field = true
    //      _#field = <init>;
    //    }
    //    return _#field;
    return new Block(<Statement>[
      new IfStatement(
          new Not(createIsSetRead()..fileOffset = fileOffset)
            ..fileOffset = fileOffset,
          new Block(<Statement>[
            new ExpressionStatement(
                createIsSetWrite(new BoolLiteral(true)..fileOffset = fileOffset)
                  ..fileOffset = fileOffset)
              ..fileOffset = fileOffset,
            new ExpressionStatement(
                createVariableWrite(initializer)..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:
                  isPotentiallyNonNullable(type, coreTypes.futureOrClass)))
        ..fileOffset = fileOffset
    ])
      ..fileOffset = fileOffset;
  } else {
    // Generate:
    //
    //    return let # = _#field in # == null ? _#field = <init> : #;
    VariableDeclaration variable = new VariableDeclaration.forValue(
        createVariableRead(needsPromotion: false)..fileOffset = fileOffset,
        type: type.withNullability(Nullability.nullable))
      ..fileOffset = fileOffset;
    return new ReturnStatement(
        new Let(
            variable,
            new ConditionalExpression(
                new MethodInvocation(
                    new VariableGet(variable)..fileOffset = fileOffset,
                    equalsName,
                    new Arguments(<Expression>[
                      new NullLiteral()..fileOffset = fileOffset
                    ])
                      ..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 with an initializer.
///
/// A late final field needs to detect writes during initialization for
/// which a `LateInitializationError` should be thrown. Late final locals
/// cannot have writes during initialization since they are not in scope in
/// their own initializer.
Statement createGetterWithInitializerWithRecheck(
    CoreTypes coreTypes,
    int fileOffset,
    String name,
    DartType type,
    String variableKindName,
    Expression initializer,
    {Expression createVariableRead({bool needsPromotion}),
    Expression createVariableWrite(Expression value),
    Expression createIsSetRead(),
    Expression createIsSetWrite(Expression value)}) {
  Expression exception = new Throw(new ConstructorInvocation(
      coreTypes.lateInitializationErrorConstructor,
      new Arguments(<Expression>[
        new StringLiteral(
            "$variableKindName '${name}' has been assigned during "
            "initialization.")
          ..fileOffset = fileOffset
      ])
        ..fileOffset = fileOffset)
    ..fileOffset = fileOffset)
    ..fileOffset = fileOffset;
  VariableDeclaration temp =
      new VariableDeclaration.forValue(initializer, type: type)
        ..fileOffset = fileOffset;
  if (isPotentiallyNullable(type, coreTypes.futureOrClass)) {
    // Generate:
    //
    //    if (!_#isSet#field) {
    //      var temp = <init>;
    //      if (_#isSet#field) throw '...'
    //      _#isSet#field = true
    //      _#field = temp;
    //    }
    //    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(
                createIsSetWrite(new BoolLiteral(true)..fileOffset = fileOffset)
                  ..fileOffset = fileOffset)
              ..fileOffset = fileOffset,
            new ExpressionStatement(
                createVariableWrite(
                    new VariableGet(temp)..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:
                  isPotentiallyNonNullable(type, coreTypes.futureOrClass)))
        ..fileOffset = fileOffset
    ])
      ..fileOffset = fileOffset;
  } else {
    // 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.withNullability(Nullability.nullable))
      ..fileOffset = fileOffset;
    return new ReturnStatement(
        new Let(
            variable,
            new ConditionalExpression(
                new MethodInvocation(
                    new VariableGet(variable)..fileOffset = fileOffset,
                    equalsName,
                    new Arguments(<Expression>[
                      new NullLiteral()..fileOffset = fileOffset
                    ])
                      ..fileOffset = fileOffset)
                  ..fileOffset = fileOffset,
                new Let(
                    temp,
                    new ConditionalExpression(
                        new MethodInvocation(
                            createVariableRead(needsPromotion: false)
                              ..fileOffset = fileOffset,
                            equalsName,
                            new Arguments(<Expression>[
                              new NullLiteral()..fileOffset = fileOffset
                            ])
                              ..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, String variableKindName,
    {Expression createVariableRead({bool needsPromotion}),
    Expression createIsSetRead()}) {
  Expression exception = new Throw(new ConstructorInvocation(
      coreTypes.lateInitializationErrorConstructor,
      new Arguments(<Expression>[
        new StringLiteral(
            "$variableKindName '${name}' has not been initialized.")
          ..fileOffset = fileOffset
      ])
        ..fileOffset = fileOffset)
    ..fileOffset = fileOffset)
    ..fileOffset = fileOffset;
  if (isPotentiallyNullable(type, coreTypes.futureOrClass)) {
    // Generate:
    //
    //    return _#isSet#field ? _#field : throw '...';
    return new ReturnStatement(
        new ConditionalExpression(
            createIsSetRead()..fileOffset = fileOffset,
            createVariableRead(
                needsPromotion:
                    isPotentiallyNonNullable(type, coreTypes.futureOrClass))
              ..fileOffset = fileOffset,
            exception,
            type)
          ..fileOffset = fileOffset)
      ..fileOffset = fileOffset;
  } else {
    // Generate:
    //
    //    return let # = _#field in # == null ? throw '...' : #;
    VariableDeclaration variable = new VariableDeclaration.forValue(
        createVariableRead()..fileOffset = fileOffset,
        type: type.withNullability(Nullability.nullable))
      ..fileOffset = fileOffset;
    return new ReturnStatement(
        new Let(
            variable,
            new ConditionalExpression(
                new MethodInvocation(
                    new VariableGet(variable)..fileOffset = fileOffset,
                    equalsName,
                    new Arguments(<Expression>[
                      new NullLiteral()..fileOffset = fileOffset
                    ])
                      ..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,
    {bool shouldReturnValue,
    Expression createVariableWrite(Expression value),
    Expression createIsSetWrite(Expression value)}) {
  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);

  if (isPotentiallyNullable(type, coreTypes.futureOrClass)) {
    // 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;
  } else {
    // 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,
    String variableKindName,
    {bool shouldReturnValue,
    Expression createVariableRead(),
    Expression createVariableWrite(Expression value),
    Expression createIsSetRead(),
    Expression createIsSetWrite(Expression value)}) {
  Expression exception = new Throw(new ConstructorInvocation(
      coreTypes.lateInitializationErrorConstructor,
      new Arguments(<Expression>[
        new StringLiteral(
            "${variableKindName} '${name}' has already been initialized.")
          ..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;
    }
  }

  if (isPotentiallyNullable(type, coreTypes.futureOrClass)) {
    // 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;
  } else {
    // Generate:
    //
    //    if (_#field == null) {
    //      return _#field = parameter;
    //    } else {
    //      throw '...';
    //    }
    return new IfStatement(
      new MethodInvocation(
          createVariableRead()..fileOffset = fileOffset,
          equalsName,
          new Arguments(
              <Expression>[new NullLiteral()..fileOffset = fileOffset])
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset,
      createReturn(createVariableWrite(
          new VariableGet(parameter)..fileOffset = fileOffset)
        ..fileOffset = fileOffset),
      new ExpressionStatement(exception)..fileOffset = fileOffset,
    )..fileOffset = fileOffset;
  }
}
