package org.elassandra.cli;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.utils.Hex;
import org.elasticsearch.cli.LoggingAwareCommand;
import org.elasticsearch.cli.Terminal;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class DecodeSmileCommand extends LoggingAwareCommand {

    private final JsonFactory jsonFactory = new JsonFactory();
    private final SmileFactory smileFactory = new SmileFactory();

    private final OptionSpec<String> smileOption = parser.acceptsAll(Arrays.asList("s", "smile"), "smile to decode (in hex format)").withRequiredArg().required().ofType(String.class);

    public DecodeSmileCommand() {
        super("Command to decode the smile form of en ElasticSearch index description");
    }

    @Override
    protected void execute(Terminal terminal, OptionSet options) throws Exception {

        final String smile = options.valueOf(smileOption);
        terminal.println(String.format("Decoding : [%s]", smile));
        terminal.println(convertToJson(smile));

    }

    private String convertToJson(String smile) {
        final byte[] bytes = Hex.hexToBytes(smile.startsWith("0x") ? smile.substring(2) : smile);
        return new String(convertToJson(bytes));
    }

    public final byte[] convertToJson(byte[] bytes) {
        final ByteArrayOutputStream bos = new ByteArrayOutputStream();

        try(JsonParser sp = smileFactory.createParser(bytes);
            JsonGenerator jg = jsonFactory.createGenerator(bos).useDefaultPrettyPrinter()) {

            while (sp.nextToken() != null) {
                jg.copyCurrentEvent(sp);
            }

        } catch (IOException e) {
            throw new InvalidRequestException(String.format("Error while converting smile to json : %s", e.getMessage()));
        }
        return bos.toByteArray();
    }
}

@@ -73,103 +73,8 @@
 ry;%0A
-import com.fasterxml.jackson.core.JsonGenerator;%0Aimport com.fasterxml.jackson.core.JsonParser;%0A
 impo
@@ -384,98 +384,361 @@
 al;%0A
-%0Aimport java.io.ByteArrayOutputStream;%0Aimport java.io.IOException;%0Aimport java.util.Arrays
+import org.elasticsearch.cluster.metadata.IndexMetaData;%0Aimport org.elasticsearch.common.xcontent.*;%0A%0Aimport java.io.ByteArrayOutputStream;%0Aimport java.io.IOException;%0Aimport java.util.Arrays;%0Aimport java.util.Collections;%0Aimport java.util.HashMap;%0Aimport java.util.Map;%0A%0Aimport static org.elasticsearch.cluster.metadata.MetaData.CONTEXT_CASSANDRA_PARAM
 ;%0A%0Ap
@@ -1342,17 +1342,16 @@
 ption %7B%0A
-%0A
         
@@ -1516,17 +1516,16 @@
 mile));%0A
-%0A
     %7D%0A%0A 
@@ -1689,19 +1689,8 @@
 urn 
-new String(
 conv
@@ -1705,17 +1705,16 @@
 n(bytes)
-)
 ;%0A    %7D%0A
@@ -1731,22 +1731,22 @@
 c final 
-byte%5B%5D
+String
  convert
@@ -1780,134 +1780,158 @@
     
-final ByteArrayOutputStream bos = new ByteArrayOutputStream();%0A%0A        try(JsonParser sp = smileFactory.createParser(
+try%7B%0A            IndexMetaData indexMetaData = IndexMetaData.FORMAT.loadLatestState(null, new NamedXContentRegistry(Collections.emptyList()), 
 bytes);%0A
     
@@ -1922,24 +1922,25 @@
 )), bytes);%0A
+%0A
             
@@ -1943,71 +1943,106 @@
     
-JsonGenerator jg = jsonFactory.createGenerator(bos).useDefaultP
+XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);%0A            builder.p
 rett
@@ -2051,16 +2051,11 @@
 rint
-er()) %7B%0A
+();
 %0A   
@@ -2067,82 +2067,253 @@
     
-while (sp.nextToken() != null) %7B%0A                jg.copyCurrentEvent(sp
+builder.startObject();%0A%0A            Map%3CString, String%3E params = new HashMap%3C%3E(1);%0A            params.put(CONTEXT_CASSANDRA_PARAM, %22true%22);%0A            IndexMetaData.Builder.toXContent(indexMetaData, builder, new ToXContent.MapParams(params)
 );%0A
+%0A
     
@@ -2316,26 +2316,96 @@
             
-%7D%0A
+builder.endObject();%0A%0A            return builder.bytes().utf8ToString();
 %0A        %7D c
@@ -2564,42 +2564,8 @@
   %7D%0A
-        return bos.toByteArray();%0A
     

fix DecodeSmile command bug