// Copyright (c) 2024, 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 'bytecode_serialization.dart';

enum LocalVariableEntryKind {
  invalid,
  scope,
  variableDeclaration,
  contextVariable,
}

abstract class LocalVariableEntry {
  static const KindMask = 0x0F;
  static const IsCapturedFlag = 1 << 4;

  LocalVariableEntryKind get kind;
  int get flags => 0;
  final int startPC;
  void writeContents(BufferedWriter writer);

  LocalVariableEntry(this.startPC);
}

class Scope extends LocalVariableEntry {
  int? endPC;
  int contextLevel;
  int position;
  int? endPosition;
  final List<VariableDeclaration> variables = <VariableDeclaration>[];

  Scope(int startPC, this.endPC, this.contextLevel, this.position,
      this.endPosition)
      : super(startPC);

  @override
  LocalVariableEntryKind get kind => LocalVariableEntryKind.scope;

  @override
  void writeContents(BufferedWriter writer) {
    final endPC = this.endPC;
    if (endPC == null) {
      throw '$this is not closed';
    }
    writer.writePackedUInt30(endPC - startPC);
    writer.writeSLEB128(contextLevel);
    writer.writePackedUInt30(position + 1);
    writer.writePackedUInt30(endPosition! + 1);
  }

  Scope.readContents(BufferedReader reader, int startPC)
      : endPC = startPC + reader.readPackedUInt30(),
        contextLevel = reader.readSLEB128(),
        position = reader.readPackedUInt30() - 1,
        endPosition = reader.readPackedUInt30() - 1,
        super(startPC);

  @override
  String toString() =>
      'scope (pc $startPC-$endPC pos $position-$endPosition context-level $contextLevel)';
}

class VariableDeclaration extends LocalVariableEntry {
  bool isCaptured;
  int index;
  int name;
  int type;
  int position;
  int initializedPosition;

  VariableDeclaration(int startPC, this.isCaptured, this.index, this.name,
      this.type, this.position, this.initializedPosition)
      : super(startPC);

  @override
  LocalVariableEntryKind get kind => LocalVariableEntryKind.variableDeclaration;

  @override
  int get flags => (isCaptured ? LocalVariableEntry.IsCapturedFlag : 0);

  @override
  void writeContents(BufferedWriter writer) {
    writer.writeSLEB128(index);
    writer.writePackedUInt30(name);
    writer.writePackedUInt30(type);
    writer.writePackedUInt30(position + 1);
    writer.writePackedUInt30(initializedPosition + 1);
  }

  VariableDeclaration.readContents(
      BufferedReader reader, int startPC, int flags)
      : isCaptured = (flags & LocalVariableEntry.IsCapturedFlag) != 0,
        index = reader.readSLEB128(),
        name = reader.readPackedUInt30(),
        type = reader.readPackedUInt30(),
        position = reader.readPackedUInt30() - 1,
        initializedPosition = reader.readPackedUInt30() - 1,
        super(startPC);

  @override
  String toString() =>
      'variable $index${isCaptured ? ' (captured)' : ''} pc $startPC, name CP#$name, type CP#$type, pos $position, init-pos $initializedPosition';
}

class ContextVariable extends LocalVariableEntry {
  int index;

  ContextVariable(int startPC, this.index) : super(startPC);

  @override
  LocalVariableEntryKind get kind => LocalVariableEntryKind.contextVariable;

  @override
  void writeContents(BufferedWriter writer) {
    writer.writeSLEB128(index);
  }

  ContextVariable.readContents(BufferedReader reader, int startPC)
      : index = reader.readSLEB128(),
        super(startPC);

  @override
  String toString() => 'context variable $index';
}

/// Keeps information about declared local variables.
class LocalVariableTable extends BytecodeDeclaration {
  final scopes = <Scope>[];
  final activeScopes = <Scope>[];
  ContextVariable? contextVariable;

  LocalVariableTable();

  void enterScope(int pc, int contextLevel, int position) {
    final scope = new Scope(pc, null, contextLevel, position, null);
    activeScopes.add(scope);
    scopes.add(scope);
  }

  void declareVariable(int pc, bool isCaptured, int index, int nameCpIndex,
      int typeCpIndex, int position, int initializedPosition) {
    final variable = new VariableDeclaration(pc, isCaptured, index, nameCpIndex,
        typeCpIndex, position, initializedPosition);
    activeScopes.last.variables.add(variable);
  }

  void leaveScope(int pc, int endPosition) {
    final scope = activeScopes.removeLast();
    scope.endPC = pc;
    scope.endPosition = endPosition;
    if (scope.variables.isEmpty &&
        activeScopes.isNotEmpty &&
        scope.contextLevel == activeScopes.last.contextLevel) {
      scopes.remove(scope);
    }
  }

  void leaveAllScopes(int pc, int endPosition) {
    while (activeScopes.isNotEmpty) {
      leaveScope(pc, endPosition);
    }
  }

  void recordContextVariable(int pc, int index) {
    assert(contextVariable == null);
    contextVariable = new ContextVariable(pc, index);
  }

  bool get isEmpty => scopes.isEmpty && contextVariable == null;

  bool get isNotEmpty => !isEmpty;

  bool get hasActiveScopes => activeScopes.isNotEmpty;

  List<LocalVariableEntry> getEntries() {
    final entries = <LocalVariableEntry>[];
    final contextVariable = this.contextVariable;
    if (contextVariable != null) {
      entries.add(contextVariable);
    }
    for (Scope scope in scopes) {
      entries.add(scope);
      entries.addAll(scope.variables);
    }
    return entries;
  }

  void write(BufferedWriter writer) {
    final entries = getEntries();
    writer.writePackedUInt30(entries.length);
    final encodeStartPC = new SLEB128DeltaEncoder();
    for (var entry in entries) {
      writer.writeByte(entry.kind.index | entry.flags);
      encodeStartPC.write(writer, entry.startPC);
      entry.writeContents(writer);
    }
  }

  LocalVariableTable.read(BufferedReader reader) {
    final int numEntries = reader.readPackedUInt30();
    final decodeStartPC = new SLEB128DeltaDecoder();
    late Scope scope;
    for (int i = 0; i < numEntries; ++i) {
      final int kindAndFlags = reader.readByte();
      final LocalVariableEntryKind kind = LocalVariableEntryKind
          .values[kindAndFlags & LocalVariableEntry.KindMask];
      final int flags = kindAndFlags & ~LocalVariableEntry.KindMask;
      final int startPC = decodeStartPC.read(reader);
      switch (kind) {
        case LocalVariableEntryKind.scope:
          scope = new Scope.readContents(reader, startPC);
          scopes.add(scope);
          break;
        case LocalVariableEntryKind.variableDeclaration:
          scope.variables.add(
              new VariableDeclaration.readContents(reader, startPC, flags));
          break;
        case LocalVariableEntryKind.contextVariable:
          contextVariable = new ContextVariable.readContents(reader, startPC);
          break;
        default:
          throw 'Unexpected entry kind ${kind}';
      }
    }
  }

  Map<int, String> getBytecodeAnnotations() {
    final map = <int, String>{};
    for (var entry in getEntries()) {
      final pc = entry.startPC;
      if (map[pc] == null) {
        map[pc] = entry.toString();
      } else {
        map[pc] = "${map[pc]}; $entry";
      }
    }
    return map;
  }
}
