package edu.buffalo.cse.blue.maybe.metadata;

import org.json.JSONArray;
import org.json.JSONObject;
import polyglot.types.SemanticException;
import polyglot.util.Position;

import java.util.LinkedList;
import java.util.List;

/**
 * Created by xcv58 on 9/14/15.
 * 1. generate metadata for maybe project.
 * 2. post metadata to maybe backend
 */
public enum Metadata {
    INSTANCE;

    // TODO: read file
    // TODO: sort by position
    // TODO: get android package name
    // TODO: generate statements, alternatives, and start/end
    private List<Statement> statementList;

    /**
     * private method to really add a maybe block or variable.
     * @param position the position of whole maybe block/variable
     * @param label the maybe label
     * @param alternatives the Position list for alternatives of this maybe block/variable
     */
    private void add(Position position, Position label, List<Position> alternatives, MaybeType type) {
        if (statementList == null) {
            statementList = new LinkedList<Statement>();
        }
//        System.out.println(position.path());
//        System.out.println(position.line());
//        System.out.println(type);
        Statement statement = new Statement(position, label, alternatives, type);
        statementList.add(statement);
    }

    /**
     * add a maybe block to metadata
     * @param position the position of whole block
     * @param label the maybe label
     * @param alternatives the Position list for alternatives of this maybe block
     */
    public void addMaybeBlock(Position position, Position label, List<Position> alternatives) {
        this.add(position, label, alternatives, MaybeType.BLOCK);
    }

    /**
     * add a maybe variable to metadata
     * @param position the position of whole block
     * @param label the maybe label
     * @param alternatives the Position list for alternatives of this maybe variable
     */
    public void addMaybeVariable(Position position, Position label, List<Position> alternatives) {
        this.add(position, label, alternatives, MaybeType.ASSIGNMENT);
    }

    /**
     * Called from Main.java to indicate the compiler finish and ready to generate metadata.
     * @throws SemanticException for duplicated labels.
     */
    public void finish() throws SemanticException {
        JSONObject jsonObject = new JSONObject();
        // TODO: generate real hash
        jsonObject.put(Constants.HASH, Constants.HASH);
        // TODO: get real package name
        jsonObject.put(Constants.PACKAGE, Constants.PACKAGE);
        JSONArray jsonArray = new JSONArray();
        for (Statement statement : statementList) {
            jsonArray.put(statement.toJSON());
        }
        jsonObject.put(Constants.STATEMENTS, jsonArray);
        // TODO: issue post and pretty to file
        System.out.println(jsonObject);
        this.clean();
    }

    /**
     * private method for cleanup internal data.
     * It's not used because current implementation only compile once for per compiler task.
     */
    private void clean(){

    }
}

@@ -167,16 +167,99 @@
 ition;%0A%0A
+import java.security.MessageDigest;%0Aimport java.security.NoSuchAlgorithmException;%0A
 import j
@@ -2182,32 +2182,1338 @@
 GNMENT);%0A    %7D%0A%0A
+    /**%0A     * private method to generate SHA224%0A     * @param jsonObject the json object contains maybe metadata%0A     * @return sha224 string for the jsonObject%0A     */%0A    private String getSHA224(JSONObject jsonObject) %7B%0A        try %7B%0A            // refer from http://www.mkyong.com/java/java-sha-hashing-example/%0A            MessageDigest instance = MessageDigest.getInstance(%22SHA-224%22);%0A            byte%5B%5D bytes = instance.digest(jsonObject.toString().getBytes());%0A%0A            StringBuilder stringBuilder = new StringBuilder();%0A            for (byte aByte : bytes) %7B%0A                stringBuilder.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));%0A            %7D%0A%0A            return stringBuilder.toString();%0A        %7D catch (NoSuchAlgorithmException e) %7B%0A            e.printStackTrace();%0A            return %22no SHA-224 algorithm found!%22;%0A        %7D%0A    %7D%0A%0A    /**%0A     * private method to generate JSONArray for statements%0A     * @param list Statement list%0A     * @return JSONArray contains JSONObjects for all Statement in list%0A     */%0A    private JSONArray getStatementJSONArray(List%3CStatement%3E list) %7B%0A        JSONArray jsonArray = new JSONArray();%0A        for (Statement statement : list) %7B%0A            jsonArray.put(statement.toJSON());%0A        %7D%0A        return jsonArray;%0A    %7D%0A%0A
     /**%0A     * C
@@ -3593,24 +3593,24 @@
 e metadata.%0A
-
      * @thro
@@ -3767,100 +3767,9 @@
 ();%0A
-        // TODO: generate real hash%0A        jsonObject.put(Constants.HASH, Constants.HASH);
 %0A
+
     
@@ -3865,24 +3865,25 @@
 CKAGE);%0A
+%0A
         
 JSONArra
@@ -3878,124 +3878,71 @@
     
-JSONArray jsonArray = new JSONArray();%0A        for (Statement statement : statementList) %7B%0A            json
+jsonObject.put(Constants.STATEMENTS, this.getStatementJSON
 Array
-.put
 (sta
@@ -3947,37 +3947,24 @@
 tatement
-.toJSON());%0A        %7D
+List));%0A
 %0A       
@@ -3993,32 +3993,44 @@
 nts.
-STATEMENTS, jsonArray
+HASH, this.getSHA224(jsonObject)
 );%0A
+%0A
     

add sha224 support