package net.openhft.chronicle.queue.impl;

import net.openhft.chronicle.queue.Compression;
import net.openhft.chronicle.wire.Marshallable;
import net.openhft.chronicle.wire.WireIn;
import net.openhft.chronicle.wire.WireKey;
import net.openhft.chronicle.wire.WireOut;
import net.openhft.lang.values.LongValue;

import java.time.ZonedDateTime;
import java.util.UUID;

import static net.openhft.lang.model.DataValueClasses.newDirectInstance;

/**
 * Data structure to bind to an off heap representation.  This is required to support persistence and sharing of this
 * data structure.
 */
class Header implements Marshallable {
    private static final long PADDED_SIZE = 256;
    // fields which can be serialized/deserialized in the normal way.
    UUID uuid;
    ZonedDateTime created;
    String user;
    String host;
    String compression;

    // support binding to off heap memory with thread safe operations.
    final LongValue writeByte = newDirectInstance(LongValue.class);
    final LongValue index2Index = newDirectInstance(LongValue.class);

    public Header init(Compression compression) {
        uuid = UUID.randomUUID();
        created = ZonedDateTime.now();
        user = System.getProperty("user.name");
        host = SingleChronicle.getHostName();
        this.compression = compression.name();
        writeByte.setOrderedValue(PADDED_SIZE);
        return this;
    }

    enum Field implements WireKey {
        type,
        uuid, created, user, host,
        writeByte, index2Index
    }

    @Override
    public void writeMarshallable(WireOut out) {
        out.write(Field.uuid).uuid(uuid)
                .write(Field.writeByte).int64(writeByte)
                .write(Field.created).zonedDateTime(created)
                .write(Field.user).text(user)
                .write(Field.host).text(host)
                .write(Field.index2Index).int64(index2Index);
        out.addPadding((int) (256 - out.bytes().position()));
    }

    @Override
    public void readMarshallable(WireIn in) {
        in.read(Field.uuid).uuid(u -> uuid = u)
                .read(Field.writeByte).int64(writeByte)
                .read(Field.created).zonedDateTime(c -> created = c)
                .read(Field.user).text(u -> user = u)
                .read(Field.host).text(h -> host = h)
                .read(Field.index2Index).int64(index2Index);
    }

    public long getWriteByte() {
        return writeByte.getVolatileValue();
    }

    public void setWriteByteLazy(long writeByte) {
        this.writeByte.setOrderedValue(writeByte);
    }
}

@@ -118,28 +118,17 @@
 le.wire.
-Marshallable
+*
 ;%0Aimport
@@ -144,115 +144,27 @@
 hft.
-chronicle.wire.WireIn;%0Aimport net.openhft.chronicle.wire.WireKey;%0Aimport net.openhft.chronicle.wire.WireOut
+lang.io.DirectStore
 ;%0Aim
@@ -562,19 +562,19 @@
 _SIZE = 
-256
+512
 ;%0A    //
@@ -736,16 +736,75 @@
 ression;
+%0A    int indexCount = 128 %3C%3C 10;%0A    int indexSpacing = 64;
 %0A%0A    //
@@ -1431,16 +1431,63 @@
 r, host,
+ compression,%0A        indexCount, indexSpacing,
 %0A       
@@ -1831,16 +1831,198 @@
 t(host)%0A
+                .write(Field.compression).text(compression)%0A                .write(Field.indexCount).int32(indexCount)%0A                .write(Field.indexSpacing).int32(indexSpacing)%0A
         
@@ -2109,11 +2109,19 @@
 t) (
-256
+PADDED_SIZE
  - o
@@ -2493,16 +2493,222 @@
 st = h)%0A
+                .read(Field.compression).text(h -%3E compression = h)%0A                .read(Field.indexCount).int32(h -%3E indexCount = h)%0A                .read(Field.indexSpacing).int32(h -%3E indexSpacing = h)%0A
         
@@ -2959,11 +2959,336 @@
 );%0A    %7D
+%0A%0A    public static void main(String... args) %7B%0A        Header h = new Header();%0A        h.init(Compression.NONE);%0A        TextWire tw = new TextWire(new DirectStore(1024).bytes());%0A        tw.writeDocument(() -%3E tw.write(%22header%22, null).writeMarshallable(h));%0A        System.out.println(tw.bytes().flip().toString());%0A%0A    %7D
 %0A%7D%0A

Add index details to the header