// Copyright (c) 2022, 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 'dart:io';
import 'dart:typed_data';

// Note that these values MUST match the arguments to -add_empty_section in
// runtime/BUILD.gn.
const String reservedSegmentName = "__CUSTOM";
const String reservedSectionName = "__space_for_note";

// Note that this value MUST match runtime/bin/snapshot_utils.cc, which looks
// specifically for the snapshot in this note.
const String snapshotNoteName = "__dart_app_snap";

/// The page size for aligning segments in MachO files. X64 MacOS uses 4k pages,
/// and ARM64 MacOS uses 16k pages, so we use 16k here.
const int segmentAlignmentLog2 = 14;
const int segmentAlignment = 1 << segmentAlignmentLog2;

/// Pads the given size so that it is a multiple of the given alignment.
int align(int size, int alignment) {
  final int unpadded = size % alignment;
  return size + (unpadded != 0 ? alignment - unpadded : 0);
}

/// A reader utility class that wraps a stream to include endian information
/// and whether or not the architecture for the MachO file uses 64-bit pointers.
class MachOReader {
  final RandomAccessFile _stream;
  final Endian _endian;

  /// Used to determine whether to read 4 or 8 bytes for the `lc_str` union
  /// type, which depends on the `__LP64__` define (e.g., is the target
  /// architecture using 64-bit pointers). May be null if no `lc_str` values
  /// will be read by this reader.
  final bool? _arch64BitPointers;

  MachOReader(this._stream, this._endian, [this._arch64BitPointers]);

  /// Reads a 16-bit unsigned integer from the contained stream.
  int readUint16() =>
      ByteData.sublistView(_stream.readSync(2)).getUint16(0, _endian);

  /// Reads a 32-bit unsigned integer from the contained stream.
  int readUint32() =>
      ByteData.sublistView(_stream.readSync(4)).getUint32(0, _endian);

  /// Reads a 64-bit unsigned integer from the contained stream.
  int readUint64() =>
      ByteData.sublistView(_stream.readSync(8)).getUint64(0, _endian);

  /// Reads a 32-bit signed integer from the contained stream.
  int readInt32() =>
      ByteData.sublistView(_stream.readSync(4)).getInt32(0, _endian);

  /// Reads an unsigned integer of the given word size from the contained
  /// stream. Throws an [ArgumentError] for if [wordSize] is not 4 or 8.
  int readUword(int wordSize) {
    switch (wordSize) {
      case 4:
        return readUint32();
      case 8:
        return readUint64();
      default:
        throw ArgumentError('Unexpected word size: $wordSize', 'wordSize');
    }
  }

  /// Reads a fixed length string from the contained stream. The string may be
  /// null terminated, in which case the returned string may contain less
  /// code points than the provided size.
  String readFixedLengthNullTerminatedString(int size) {
    final buffer = _stream.readSync(size);
    return String.fromCharCodes(buffer.takeWhile((value) => value != 0));
  }

  /// Reads an `lc_str` value from the contained stream. For 32-bit
  /// architectures, or 64-bit architectures using 32-bit pointers, this is
  /// 32 bits. On 64-bit architectures using 64-bit pointers, this is 64 bits.
  int readLCString() => _arch64BitPointers! ? readUint64() : readUint32();

  /// Reads [size] bytes from the contained stream.
  Uint8List readBytes(int size) => _stream.readSync(size);
}

/// A writer utility class that wraps a stream to include endian information
/// and whether or not the architecture for the MachO file uses 64-bit pointers.
class MachOWriter {
  final RandomAccessFile _stream;
  final Endian _endian;

  /// Used to determine whether to write 4 or 8 bytes for the `lc_str` union
  /// type, which depends on the `__LP64__` define (e.g., is the target
  /// architecture using 64-bit pointers). May be null if no `lc_str` values
  /// will be written by this reader.
  final bool? _arch64BitPointers;

  MachOWriter(this._stream, this._endian, [this._arch64BitPointers]);

  /// Writes a 16-bit unsigned integer to the contained stream. Throws
  /// a [FormatException] if the value is negative or does not fit in 16 bits.
  void writeUint16(int value) {
    if (value < 0) {
      throw FormatException("Attempted to write a negative value $value");
    }
    if ((value >> 16) != 0) {
      throw FormatException("Attempted to write an unsigned value that doesn't "
          "fit in 16 bits: $value");
    }
    final buffer = ByteData(2)..setUint16(0, value, _endian);
    _stream.writeFromSync(Uint8List.sublistView(buffer));
  }

  /// Writes a 32-bit unsigned integer to the contained stream. Throws
  /// a [FormatException] if the value is negative or does not fit in 32 bits.
  void writeUint32(int value) {
    if (value < 0) {
      throw FormatException("Attempted to write a negative value $value");
    }
    if ((value >> 32) != 0) {
      throw FormatException("Attempted to write an unsigned value that doesn't "
          "fit in 32 bits: $value");
    }
    final buffer = ByteData(4)..setUint32(0, value, _endian);
    _stream.writeFromSync(Uint8List.sublistView(buffer));
  }

  /// Writes a 64-bit unsigned integer to the contained stream.
  void writeUint64(int value) {
    final buffer = ByteData(8)..setUint64(0, value, _endian);
    _stream.writeFromSync(Uint8List.sublistView(buffer));
  }

  /// Writes a 32-bit unsigned integer to the contained stream. Throws
  /// a [FormatException] if the signed value does not fit in 32 bits.
  void writeInt32(int value) {
    if (((value < 0 ? ~value : value) >> 31) != 0) {
      throw FormatException("Attempted to write a signed value that doesn't "
          "fit in 32 bits: $value");
    }
    final buffer = ByteData(4)..setInt32(0, value, _endian);
    _stream.writeFromSync(Uint8List.sublistView(buffer));
  }

  /// Writes an unsigned integer with a given word size to the contained
  /// stream. Throws an [ArgumentError] for if [wordSize] is not 4 or 8.
  void writeUword(int value, int wordSize) {
    switch (wordSize) {
      case 4:
        return writeUint32(value);
      case 8:
        return writeUint64(value);
      default:
        throw ArgumentError('Unexpected word size: $wordSize', 'wordSize');
    }
  }

  /// Writes the given string as an ASCII-encoded null terminated string
  /// with a given fixed length. Throws a format exception if the ASCII
  /// character length of the string is longer than the given length.
  /// If the ASCII character length of the string is the same as the given
  /// length, there will be no null terminator in the written data.
  void writeFixedLengthNullTerminatedString(String s, int length) {
    final Uint8List buffer = Uint8List(length);
    final encoded = ascii.encode(s);
    if (encoded.length > length) {
      throw FormatException('Attempted to write a string longer than $length '
          'characters: "$s"');
    }
    buffer.setRange(0, encoded.length, encoded);
    _stream.writeFromSync(buffer);
  }

  /// Writes an `lc_str` value to the contained stream. For 32-bit
  /// architectures, or 64-bit architectures using 32-bit pointers, this is
  /// 32 bits. On 64-bit architectures using 64-bit pointers, this is 64 bits.
  void writeLCString(int value) =>
      _arch64BitPointers! ? writeUint64(value) : writeUint32(value);

  /// Writes the given bytes to the contained stream.
  void writeBytes(Uint8List bytes) => _stream.writeFromSync(bytes);
}
