package eu.mulk.jgvariant.ostree;

import eu.mulk.jgvariant.core.Decoder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.List;

/**
 * A payload file from a static delta.
 *
 * <p>The first byte is a compression byte: {@code 0} for none, {@code 'x'} for LZMA. The actual
 * GVariant data begins right after.
 *
 * <p>Reference: {@code
 * ostree-repo-static-delta-private.h#OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0}
 *
 * @param fileModes the {@link FileMode}s of the files generated by this delta payload.
 * @param xattrs the {@link Xattr}s of the files generated by this delta payload.
 * @param rawDataSource the data bytes used in the delta operations.
 * @param operations the operations to apply during delta patching.
 * @see DeltaSuperblock
 */
public record DeltaPartPayload(
    List<FileMode> fileModes,
    List<List<Xattr>> xattrs,
    ByteString rawDataSource,
    List<DeltaOperation> operations) {

  private static final Decoder<DeltaPartPayload> DECODER =
      Decoder.ofStructure(
              DeltaPartPayload.class,
              Decoder.ofArray(FileMode.decoder()),
              Decoder.ofArray(Decoder.ofArray(Xattr.decoder())),
              ByteString.decoder(),
              ByteString.decoder().map(DeltaPartPayload::parseDeltaOperationList))
          .contramap(DeltaPartPayload::preparse);

  private static ByteBuffer preparse(ByteBuffer byteBuffer) {
    byte compressionByte = byteBuffer.get(0);
    return switch (compressionByte) {
      case 0 -> byteBuffer.slice(1, byteBuffer.limit());
      case (byte) 'x' -> throw new UnsupportedOperationException(
          "LZMA compression of static deltas is unsupported");
      default -> throw new IllegalArgumentException(
          "unrecognized compression byte '%d'".formatted(compressionByte));
    };
  }

  private static List<DeltaOperation> parseDeltaOperationList(ByteString byteString) {
    return byteString.stream().map(DeltaOperation::valueOf).toList();
  }

  /**
   * A file mode triple (UID, GID, and permission bits).
   *
   * @param uid
   * @param gid
   * @param mode
   */
  public record FileMode(int uid, int gid, int mode) {

    private static final Decoder<FileMode> DECODER =
        Decoder.ofStructure(
            FileMode.class,
            Decoder.ofInt().withByteOrder(ByteOrder.LITTLE_ENDIAN),
            Decoder.ofInt().withByteOrder(ByteOrder.LITTLE_ENDIAN),
            Decoder.ofInt().withByteOrder(ByteOrder.LITTLE_ENDIAN));

    /**
     * Acquires a {@link Decoder} for the enclosing type.
     *
     * @return a possibly shared {@link Decoder}.
     */
    public static Decoder<FileMode> decoder() {
      return DECODER;
    }
  }

  /**
   * Acquires a {@link Decoder} for the enclosing type.
   *
   * <p>FIXME: The first byte is actually a compression byte: {@code 0} for none, {@code 'x'} for
   * LZMA.
   *
   * @return a possibly shared {@link Decoder}.
   */
  public static Decoder<DeltaPartPayload> decoder() {
    return DECODER;
  }
}
