package eu.mulk.jgvariant.ostree;

import eu.mulk.jgvariant.core.Decoder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.List;
import org.tukaani.xz.XZInputStream;

/**
 * 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);
    var dataSlice = byteBuffer.slice(1, byteBuffer.limit() - 1);
    return switch (compressionByte) {
      case 0 -> dataSlice;
      case (byte) 'x' -> {
        try {
          var dataBytes = new byte[dataSlice.limit()];
          dataSlice.get(dataBytes);
          var decompressingInputStream = new XZInputStream(new ByteArrayInputStream(dataBytes));

          var decompressedOutputStream = new ByteArrayOutputStream();
          decompressingInputStream.transferTo(decompressedOutputStream);

          yield ByteBuffer.wrap(decompressedOutputStream.toByteArray());
        } catch (IOException e) {
          // impossible
          throw new UncheckedIOException(e);
        }
      }
      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;
  }
}
