// Copyright (c) 2018, 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 'dart:convert';
import 'package:kernel/binary/ast_to_binary.dart';
import 'data_sink.dart';

/// [DataSink] that writes data as a sequence of bytes.
///
/// This data sink works together with [BinarySourceWriter].
class BinaryDataSink implements DataSink {
  final Sink<List<int>> sink;
  // Nullable and non-final to allow storage to be released.
  BufferedSink? _bufferedSink;
  final Map<int, int> _deferredOffsetToSize = {};
  int _length = 0;

  BinaryDataSink(this.sink) : _bufferedSink = BufferedSink(sink);

  @override
  int get length => _length;

  @override
  void beginTag(String tag) {
    // TODO(johnniwinther): Support tags in binary serialization?
  }

  @override
  void endTag(String tag) {
    // TODO(johnniwinther): Support tags in binary serialization?
  }

  @override
  void writeString(String value) {
    List<int> bytes = utf8.encode(value);
    writeInt(bytes.length);
    _bufferedSink!.addBytes(bytes);
    _length += bytes.length;
  }

  @override
  void writeInt(int value) {
    assert(value >= 0 && value >> 30 == 0);
    if (value < 0x80) {
      _bufferedSink!.addByte(value);
      _length += 1;
    } else if (value < 0x4000) {
      _bufferedSink!.addByte2((value >> 8) | 0x80, value & 0xFF);
      _length += 2;
    } else {
      _bufferedSink!.addByte4((value >> 24) | 0xC0, (value >> 16) & 0xFF,
          (value >> 8) & 0xFF, value & 0xFF);
      _length += 4;
    }
  }

  void _writeUInt32(int value) {
    _length += 4;
    _bufferedSink!.addByte4((value >> 24) & 0xFF, (value >> 16) & 0xFF,
        (value >> 8) & 0xFF, value & 0xFF);
  }

  @override
  void writeDeferred(void writer()) {
    final indexOffset = _length;
    writeInt(0); // Padding so the offset won't collide with a nested write.
    final dataStartOffset = _length;
    writer();
    _deferredOffsetToSize[indexOffset] = _length - dataStartOffset;
  }

  @override
  void writeEnum(dynamic value) {
    writeInt(value.index);
  }

  @override
  void close() {
    final deferredDataStart = _length;
    writeInt(_deferredOffsetToSize.length);
    for (final entry in _deferredOffsetToSize.entries) {
      writeInt(entry.key);
      writeInt(entry.value);
    }
    _writeUInt32(deferredDataStart);
    _bufferedSink!.flushAndDestroy();
    _bufferedSink = null;
    _deferredOffsetToSize.clear();
    sink.close();
  }
}
