// Copyright (c) 2021, 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.

// @dart=2.12

import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/type_algebra.dart';

import '../../options.dart';

class _Reader {
  final Procedure _procedure;
  final FunctionType _type;
  late final FunctionType _typeWithoutTypeParameters;

  _Reader(this._procedure) : _type = _procedure.getterType as FunctionType {
    _typeWithoutTypeParameters = _type.withoutTypeParameters;
  }
}

class LateLowering {
  final CoreTypes _coreTypes;

  final bool _omitLateNames;

  final _Reader _readLocal;
  final _Reader _readField;
  final _Reader _readInitialized;
  final _Reader _readInitializedFinal;

  // Each map contains the mapping from late local variables to cells for a
  // given function scope. All late local variables are lowered to cells.
  final List<Map<VariableDeclaration, VariableDeclaration>?> _variableCells =
      [];

  // Uninitialized late static fields are lowered to cells.
  final Map<Field, Field> _fieldCells = {};

  // Late instance fields are lowered to a backing field (plus a getter/setter
  // pair).
  final Map<Field, Field> _backingInstanceFields = {};

  Member? _contextMember;

  LateLowering(this._coreTypes, CompilerOptions? _options)
      : _omitLateNames = _options?.omitLateNames ?? false,
        _readLocal = _Reader(_coreTypes.cellReadLocal),
        _readField = _Reader(_coreTypes.cellReadField),
        _readInitialized = _Reader(_coreTypes.initializedCellRead),
        _readInitializedFinal = _Reader(_coreTypes.initializedCellReadFinal);

  Nullability get nonNullable => _contextMember!.enclosingLibrary.nonNullable;

  bool _shouldLowerVariable(VariableDeclaration variable) => variable.isLate;

  bool _shouldLowerUninitializedVariable(VariableDeclaration variable) =>
      _shouldLowerVariable(variable) && variable.initializer == null;

  bool _shouldLowerInitializedVariable(VariableDeclaration variable) =>
      _shouldLowerVariable(variable) && variable.initializer != null;

  bool _shouldLowerStaticField(Field field) =>
      field.isLate && field.isStatic && field.initializer == null;

  bool _shouldLowerInstanceField(Field field) =>
      field.isLate && !field.isStatic;

  Name _mangleFieldCellName(Field field) {
    assert(_shouldLowerStaticField(field));
    return Name('_#${field.name.text}', field.enclosingLibrary);
  }

  Name _mangleFieldName(Field field) {
    assert(_shouldLowerInstanceField(field));
    Class cls = field.enclosingClass!;
    return Name('_#${cls.name}#${field.name.text}', field.enclosingLibrary);
  }

  ConstructorInvocation _callCellConstructor(Expression name, int fileOffset) =>
      _omitLateNames
          ? _callCellUnnamedConstructor(fileOffset)
          : _callCellNamedConstructor(name, fileOffset);

  ConstructorInvocation _callCellUnnamedConstructor(int fileOffset) =>
      ConstructorInvocation(_coreTypes.cellConstructor,
          Arguments.empty()..fileOffset = fileOffset)
        ..fileOffset = fileOffset;

  ConstructorInvocation _callCellNamedConstructor(
          Expression name, int fileOffset) =>
      ConstructorInvocation(_coreTypes.cellNamedConstructor,
          Arguments([name])..fileOffset = fileOffset)
        ..fileOffset = fileOffset;

  ConstructorInvocation _callInitializedCellConstructor(
          Expression name, Expression initializer, int fileOffset) =>
      _omitLateNames
          ? _callInitializedCellUnnamedConstructor(initializer, fileOffset)
          : _callInitializedCellNamedConstructor(name, initializer, fileOffset);

  ConstructorInvocation _callInitializedCellUnnamedConstructor(
          Expression initializer, int fileOffset) =>
      ConstructorInvocation(_coreTypes.initializedCellConstructor,
          Arguments([initializer])..fileOffset = fileOffset)
        ..fileOffset = fileOffset;

  ConstructorInvocation _callInitializedCellNamedConstructor(
          Expression name, Expression initializer, int fileOffset) =>
      ConstructorInvocation(_coreTypes.initializedCellNamedConstructor,
          Arguments([name, initializer])..fileOffset = fileOffset)
        ..fileOffset = fileOffset;

  StringLiteral _nameLiteral(String? name, int fileOffset) =>
      StringLiteral(name ?? '')..fileOffset = fileOffset;

  InstanceInvocation _callReader(
      _Reader reader, Expression receiver, DartType type, int fileOffset) {
    Procedure procedure = reader._procedure;
    List<DartType> typeArguments = [type];
    return InstanceInvocation(
        InstanceAccessKind.Instance,
        receiver,
        procedure.name,
        Arguments(const [], types: typeArguments)..fileOffset = fileOffset,
        interfaceTarget: procedure,
        functionType:
            Substitution.fromPairs(reader._type.typeParameters, typeArguments)
                    .substituteType(reader._typeWithoutTypeParameters)
                as FunctionType)
      ..fileOffset = fileOffset;
  }

  InstanceSet _callSetter(Procedure _setter, Expression receiver,
          Expression value, int fileOffset) =>
      InstanceSet(InstanceAccessKind.Instance, receiver, _setter.name, value,
          interfaceTarget: _setter)
        ..fileOffset = fileOffset;

  StaticInvocation _callIsSentinel(Expression value, int fileOffset) =>
      StaticInvocation(_coreTypes.isSentinelMethod,
          Arguments([value])..fileOffset = fileOffset)
        ..fileOffset = fileOffset;

  void exitLibrary() {
    assert(_variableCells.isEmpty);
    _fieldCells.clear();
    _backingInstanceFields.clear();
  }

  void enterFunction() {
    _variableCells.add(null);
  }

  void exitFunction() {
    _variableCells.removeLast();
  }

  VariableDeclaration? _lookupVariableCell(VariableDeclaration variable) {
    assert(_shouldLowerVariable(variable));
    for (final scope in _variableCells) {
      if (scope == null) continue;
      final cell = scope[variable];
      if (cell != null) return cell;
    }
    return null;
  }

  VariableDeclaration _addToCurrentScope(
      VariableDeclaration variable, VariableDeclaration cell) {
    assert(_shouldLowerVariable(variable));
    assert(_lookupVariableCell(variable) == null);
    return (_variableCells.last ??= {})[variable] = cell;
  }

  VariableDeclaration _variableCell(VariableDeclaration variable) {
    assert(_shouldLowerVariable(variable));
    final cell = _lookupVariableCell(variable);
    if (cell != null) return cell;
    return variable.initializer == null
        ? _uninitializedVariableCell(variable)
        : _initializedVariableCell(variable);
  }

  VariableDeclaration _uninitializedVariableCell(VariableDeclaration variable) {
    assert(_shouldLowerUninitializedVariable(variable));
    int fileOffset = variable.fileOffset;
    String? name = variable.name;
    final cell = VariableDeclaration(name,
        initializer:
            _callCellConstructor(_nameLiteral(name, fileOffset), fileOffset),
        type: InterfaceType(_coreTypes.cellClass, nonNullable),
        isFinal: true)
      ..fileOffset = fileOffset;

    return _addToCurrentScope(variable, cell);
  }

  FunctionExpression _initializerClosure(
      Expression initializer, DartType type) {
    int fileOffset = initializer.fileOffset;
    ReturnStatement body = ReturnStatement(initializer)
      ..fileOffset = fileOffset;
    FunctionNode closure = FunctionNode(body, returnType: type)
      ..fileOffset = fileOffset;
    return FunctionExpression(closure)..fileOffset = fileOffset;
  }

  VariableDeclaration _initializedVariableCell(VariableDeclaration variable) {
    assert(_shouldLowerInitializedVariable(variable));
    int fileOffset = variable.fileOffset;
    String? name = variable.name;
    final cell = VariableDeclaration(name,
        initializer: _callInitializedCellConstructor(
            _nameLiteral(name, fileOffset),
            _initializerClosure(variable.initializer!, variable.type),
            fileOffset),
        type: InterfaceType(_coreTypes.initializedCellClass, nonNullable),
        isFinal: true)
      ..fileOffset = fileOffset;
    return _addToCurrentScope(variable, cell);
  }

  TreeNode transformVariableDeclaration(
      VariableDeclaration variable, Member? contextMember) {
    _contextMember = contextMember;

    if (!_shouldLowerVariable(variable)) return variable;

    // A [VariableDeclaration] being used as a statement must be a direct child
    // of a [Block].
    if (variable.parent is! Block) return variable;

    return _variableCell(variable);
  }

  VariableGet _variableCellRead(VariableDeclaration variable, int fileOffset) {
    assert(_shouldLowerVariable(variable));
    return VariableGet(_variableCell(variable))..fileOffset = fileOffset;
  }

  TreeNode transformVariableGet(VariableGet node, Member contextMember) {
    _contextMember = contextMember;

    VariableDeclaration variable = node.variable;
    if (!_shouldLowerVariable(variable)) return node;

    int fileOffset = node.fileOffset;
    VariableGet cell = _variableCellRead(variable, fileOffset);
    _Reader reader = variable.initializer == null
        ? _readLocal
        : (variable.isFinal ? _readInitializedFinal : _readInitialized);
    return _callReader(
        reader, cell, node.promotedType ?? variable.type, fileOffset);
  }

  TreeNode transformVariableSet(VariableSet node, Member contextMember) {
    _contextMember = contextMember;

    VariableDeclaration variable = node.variable;
    if (!_shouldLowerVariable(variable)) return node;

    int fileOffset = node.fileOffset;
    VariableGet cell = _variableCellRead(variable, fileOffset);
    Procedure setter = variable.initializer == null
        ? (variable.isFinal
            ? _coreTypes.cellFinalLocalValueSetter
            : _coreTypes.cellValueSetter)
        : (variable.isFinal
            ? _coreTypes.initializedCellFinalValueSetter
            : _coreTypes.initializedCellValueSetter);
    return _callSetter(setter, cell, node.value, fileOffset);
  }

  Field _fieldCell(Field field) {
    assert(_shouldLowerStaticField(field));
    return _fieldCells.putIfAbsent(field, () {
      int fileOffset = field.fileOffset;
      Name name = field.name;
      Uri fileUri = field.fileUri;
      DartType type = field.type;
      // We need to unbind the canonical name since we reuse the reference but
      // change the name.
      field.fieldReference.canonicalName?.unbind();
      Field fieldCell = Field.immutable(_mangleFieldCellName(field),
          type: InterfaceType(_coreTypes.cellClass, nonNullable),
          initializer: _callCellConstructor(
              _nameLiteral(name.text, fileOffset), fileOffset),
          isFinal: true,
          isStatic: true,
          fileUri: fileUri,
          fieldReference: field.fieldReference)
        ..fileOffset = fileOffset
        ..isNonNullableByDefault = true;
      StaticGet fieldCellAccess() =>
          StaticGet(fieldCell)..fileOffset = fileOffset;

      Procedure getter = Procedure(
          name,
          ProcedureKind.Getter,
          FunctionNode(
              ReturnStatement(
                  _callReader(_readField, fieldCellAccess(), type, fileOffset))
                ..fileOffset = fileOffset,
              returnType: type)
            ..fileOffset = fileOffset,
          isStatic: true,
          fileUri: fileUri,
          reference: field.getterReference)
        ..fileOffset = fileOffset
        ..isNonNullableByDefault = true;

      VariableDeclaration setterValue = VariableDeclaration('value', type: type)
        ..fileOffset = fileOffset;
      VariableGet setterValueRead() =>
          VariableGet(setterValue)..fileOffset = fileOffset;

      Procedure setter = Procedure(
          name,
          ProcedureKind.Setter,
          FunctionNode(
              ReturnStatement(_callSetter(
                  field.isFinal
                      ? _coreTypes.cellFinalFieldValueSetter
                      : _coreTypes.cellValueSetter,
                  fieldCellAccess(),
                  setterValueRead(),
                  fileOffset))
                ..fileOffset = fileOffset,
              positionalParameters: [setterValue],
              returnType: VoidType())
            ..fileOffset = fileOffset,
          isStatic: true,
          fileUri: fileUri,
          reference: field.setterReference)
        ..fileOffset = fileOffset
        ..isNonNullableByDefault = true;

      TreeNode parent = field.parent!;
      if (parent is Class) {
        parent.addProcedure(getter);
        parent.addProcedure(setter);
      } else if (parent is Library) {
        parent.addProcedure(getter);
        parent.addProcedure(setter);
      }

      return fieldCell;
    });
  }

  Field _backingInstanceField(Field field) {
    assert(_shouldLowerInstanceField(field));
    return _backingInstanceFields[field] ??=
        _computeBackingInstanceField(field);
  }

  Field _computeBackingInstanceField(Field field) {
    assert(_shouldLowerInstanceField(field));
    assert(!_backingInstanceFields.containsKey(field));
    int fileOffset = field.fileOffset;
    Uri fileUri = field.fileUri;
    Name name = field.name;
    String nameText = name.text;
    Name mangledName = _mangleFieldName(field);
    DartType type = field.type;
    Expression? initializer = field.initializer;
    Class enclosingClass = field.enclosingClass!;

    // We need to unbind the canonical name since we reuse the reference but
    // change the name.
    field.fieldReference.canonicalName?.unbind();
    Field backingField = Field.mutable(mangledName,
        type: type,
        initializer: StaticInvocation(_coreTypes.createSentinelMethod,
            Arguments(const [], types: [type])..fileOffset = fileOffset)
          ..fileOffset = fileOffset,
        fileUri: fileUri,
        fieldReference: field.fieldReference)
      ..fileOffset = fileOffset
      ..isNonNullableByDefault = true
      ..isInternalImplementation = true;
    InstanceGet fieldRead() => InstanceGet(InstanceAccessKind.Instance,
        ThisExpression()..fileOffset = fileOffset, mangledName,
        interfaceTarget: backingField, resultType: type)
      ..fileOffset = fileOffset;
    InstanceSet fieldWrite(Expression value) => InstanceSet(
        InstanceAccessKind.Instance,
        ThisExpression()..fileOffset = fileOffset,
        mangledName,
        value,
        interfaceTarget: backingField)
      ..fileOffset = fileOffset;

    Statement getterBody() {
      if (initializer == null) {
        // The lowered getter for `late T field;` and `late final T field;` is
        //
        // T get field => _lateReadCheck<T>(this._#field, "field");
        return ReturnStatement(
            StaticInvocation(
                _coreTypes.lateReadCheck,
                Arguments([fieldRead(), _nameLiteral(nameText, fileOffset)],
                    types: [type])
                  ..fileOffset = fileOffset)
              ..fileOffset = fileOffset)
          ..fileOffset = fileOffset;
      } else if (field.isFinal) {
        // The lowered getter for `late final T field = e;` is
        //
        // T get field {
        //   var value = this._#field;
        //   if (isSentinel(value)) {
        //     final result = e;
        //     _lateInitializeOnceCheck(this._#field, "field");
        //     value = this._#field = result;
        //   }
        //   return value;
        // }
        VariableDeclaration value =
            VariableDeclaration('value', initializer: fieldRead(), type: type)
              ..fileOffset = fileOffset;
        VariableGet valueRead() => VariableGet(value)..fileOffset = fileOffset;
        VariableDeclaration result = VariableDeclaration('result',
            initializer: initializer, type: type, isFinal: true)
          ..fileOffset = fileOffset;
        VariableGet resultRead() =>
            VariableGet(result)..fileOffset = fileOffset;
        return Block([
          value,
          IfStatement(
              _callIsSentinel(valueRead(), fileOffset),
              Block([
                result,
                ExpressionStatement(
                    StaticInvocation(
                        _coreTypes.lateInitializeOnceCheck,
                        Arguments(
                            [fieldRead(), _nameLiteral(nameText, fileOffset)])
                          ..fileOffset = fileOffset)
                      ..fileOffset = fileOffset)
                  ..fileOffset = fileOffset,
                ExpressionStatement(
                    VariableSet(value, fieldWrite(resultRead()))
                      ..fileOffset = fileOffset)
                  ..fileOffset = fileOffset
              ])
                ..fileOffset = fileOffset,
              null)
            ..fileOffset = fileOffset,
          ReturnStatement(valueRead())..fileOffset = fileOffset
        ])
          ..fileOffset = fileOffset;
      } else {
        // The lowered getter for `late T field = e;` is
        //
        // T get field {
        //   var value = this._#field;
        //   if (isSentinel(value)) {
        //     value = this._#field = e;
        //   }
        //   return value;
        // }
        VariableDeclaration value =
            VariableDeclaration('value', initializer: fieldRead(), type: type)
              ..fileOffset = fileOffset;
        VariableGet valueRead() => VariableGet(value)..fileOffset = fileOffset;
        return Block([
          value,
          IfStatement(
              _callIsSentinel(valueRead(), fileOffset),
              ExpressionStatement(
                  VariableSet(value, fieldWrite(initializer))
                    ..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
              null)
            ..fileOffset = fileOffset,
          ReturnStatement(valueRead())..fileOffset = fileOffset
        ])
          ..fileOffset = fileOffset;
      }
    }

    Procedure getter = Procedure(name, ProcedureKind.Getter,
        FunctionNode(getterBody(), returnType: type)..fileOffset = fileOffset,
        fileUri: fileUri, reference: field.getterReference)
      ..fileOffset = fileOffset
      ..isNonNullableByDefault = true;
    enclosingClass.addProcedure(getter);

    VariableDeclaration setterValue = VariableDeclaration('value', type: type)
      ..fileOffset = fileOffset;
    VariableGet setterValueRead() =>
        VariableGet(setterValue)..fileOffset = fileOffset;

    Statement? setterBody() {
      if (!field.isFinal) {
        // The lowered setter for `late T field;` and `late T field = e;` is
        //
        // set field(T value) {
        //   this._#field = value;
        // }
        return ExpressionStatement(fieldWrite(setterValueRead()))
          ..fileOffset = fileOffset;
      } else if (initializer == null) {
        // The lowered setter for `late final T field;` is
        //
        // set field(T value) {
        //   _lateWriteOnceCheck(this._#field, "field");
        //   this._#field = value;
        // }
        return Block([
          ExpressionStatement(
              StaticInvocation(
                  _coreTypes.lateWriteOnceCheck,
                  Arguments([fieldRead(), _nameLiteral(nameText, fileOffset)])
                    ..fileOffset = fileOffset)
                ..fileOffset = fileOffset)
            ..fileOffset = fileOffset,
          ExpressionStatement(fieldWrite(setterValueRead()))
            ..fileOffset = fileOffset
        ])
          ..fileOffset = fileOffset;
      } else {
        // There is no setter for `late final T field = e;`.
        return null;
      }
    }

    Statement? body = setterBody();
    if (body != null) {
      Procedure setter = Procedure(
          name,
          ProcedureKind.Setter,
          FunctionNode(body,
              positionalParameters: [setterValue], returnType: VoidType())
            ..fileOffset = fileOffset,
          fileUri: fileUri,
          reference: field.setterReference)
        ..fileOffset = fileOffset
        ..isNonNullableByDefault = true;
      enclosingClass.addProcedure(setter);
    }

    return backingField;
  }

  TreeNode transformField(Field field, Member contextMember) {
    _contextMember = contextMember;

    if (_shouldLowerStaticField(field)) return _fieldCell(field);
    if (_shouldLowerInstanceField(field)) return _backingInstanceField(field);

    return field;
  }
}
