// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

package com.yahoo.search.logging;

import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.yahoo.search.Query;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.util.Base64;

public class LoggerEntry {

    private final Long timestamp;
    private final Query query;
    private final ByteBuffer blob;

    private LoggerEntry(Builder builder) {
        timestamp = builder.timestamp;  // or set automatically if not set
        query = builder.query;
        blob = builder.blob;
    }

    public Long timestamp() {
        return timestamp;
    }

    public Query query() {
        return query;
    }

    public String queryString() {
        String queryString = null;
        if (query != null) {
            if (query.getHttpRequest() != null && query.getHttpRequest().getUri() != null) {
                queryString = query.getHttpRequest().getUri().getPath();
                if (query.getHttpRequest().getUri().getQuery() != null) {
                    queryString += "?" + query.getHttpRequest().getUri().getRawQuery();
                }
            }
        }
        return queryString;
    }

    public ByteBuffer blob() {
        return blob;
    }

    public String toString() {
        return toJson();
    }

    public String toJson() {
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            JsonGenerator g = new JsonFactory().createGenerator(out, JsonEncoding.UTF8);
            g.writeStartObject();

            g.writeNumberField("timestamp", timestamp == null ? 0 : timestamp);
            g.writeStringField("query", queryString());
            g.writeStringField("blob", Base64.getEncoder().encodeToString(blob.array()));

            g.writeEndObject();
            g.close();
            return out.toString();

        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    public static class Builder {

        private final Logger logger;

        private Long timestamp;
        private Query query;
        private ByteBuffer blob;

        public Builder(Logger logger) {
            this.logger = logger;
        }

        public Builder timestamp(long timestamp) {
            this.timestamp = timestamp;
            return this;
        }

        public Builder query(Query query) {
            this.query = query;
            return this;
        }

        public Builder blob(byte[] bytes) {
            blob = ByteBuffer.allocate(bytes.length);
            blob.put(bytes).limit(blob.position()).position(0);
            return this;
        }

        public boolean send() {
            return logger.send(new LoggerEntry(this));
        }

    }


}

@@ -309,16 +309,81 @@
 .Query;%0A
+import com.yahoo.slime.JsonDecoder;%0Aimport com.yahoo.slime.Slime;
 %0Aimport 
@@ -2234,32 +2234,608 @@
        %7D%0A    %7D%0A%0A
+    // TODO: Rename method here and above? (serialize/deserialize)%0A    // TODO: Use Slime or Jackson for both%0A    public static LoggerEntry fromJson(byte%5B%5D content) throws IOException %7B%0A        var decoder = new JsonDecoder();%0A        var slime = decoder.decode(new Slime(), content);%0A%0A        var timestamp = slime.get().field(%22timestamp%22).asLong();%0A        var query = new Query(slime.get().field(%22query%22).asString());%0A        var blob = slime.get().field(%22blob%22).asData();%0A%0A        return new LoggerEntry(new Builder().timestamp(timestamp).query(query).blob(blob));%0A    %7D%0A%0A
     public stati
@@ -2852,16 +2852,16 @@
 ilder %7B%0A
-
 %0A       
@@ -2982,24 +2982,99 @@
 ffer blob;%0A%0A
+        // For testing%0A        public Builder() %7B this(entry -%3E false); %7D%0A%0A
         publ
@@ -3685,14 +3685,13 @@
  %7D%0A%0A
+
     %7D%0A%0A
-%0A
 %7D%0A

Add a fromJson method to LoggerEntry (use when reading spooler files)