package org.commcare.recovery.measures;

import org.commcare.core.network.AuthInfo;
import org.commcare.network.GetAndParseActor;
import org.commcare.preferences.ServerUrls;
import org.commcare.util.LogTypes;
import org.javarosa.core.services.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;

/**
 * Created by amstone326 on 5/8/18.
 */

public class RecoveryMeasuresRequester extends GetAndParseActor {

    private static final String NAME = "recovery measures";
    private static final String TAG = RecoveryMeasuresRequester.class.getSimpleName();


    public RecoveryMeasuresRequester() {
        super(NAME, TAG, ServerUrls.PREFS_RECOVERY_MEASURES_URL_KEY);
    }

    @Override
    public HashMap<String, String> getRequestParams() {
        return new HashMap<>();
    }

    @Override
    public AuthInfo getAuth() {
        return new AuthInfo.NoAuth();
    }

    @Override
    public void makeRequest() {
        // mock waiting for request response
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {

        }
        // Parse mock response
    }

    @Override
    public void parseResponse(JSONObject responseAsJson) {
        //if (checkForAppIdMatch(responseAsJson)) {
            try {
                if (responseAsJson.has("recovery_measures")) {
                    boolean recoveryMeasuresStored = false;
                    JSONArray recoveryMeasures = responseAsJson.getJSONArray("recovery_measures");
                    for (int i = 0; i < recoveryMeasures.length(); i++) {
                        JSONObject recoveryMeasure = recoveryMeasures.getJSONObject(i);
                        recoveryMeasuresStored = parseRecoveryMeasure(recoveryMeasure) || recoveryMeasuresStored;
                    }
                    if (recoveryMeasuresStored) {
                        RecoveryMeasuresManager.executePendingMeasures();
                    }
                }
            } catch (JSONException e) {
                Logger.log(LogTypes.TYPE_ERROR_SERVER_COMMS,
                        "recovery_measures array in heartbeat response not properly formatted: " + e.getMessage());
            }
        //}
    }

    private static boolean parseRecoveryMeasure(JSONObject recoveryMeasureObject) {
        try {
            int sequenceNumber = Integer.parseInt(recoveryMeasureObject.getString("sequence_number"));
            String type = recoveryMeasureObject.getString("type");
            String ccVersionMin = recoveryMeasureObject.getString("cc_version_min");
            String ccVersionMax = recoveryMeasureObject.getString("cc_version_max");
            int appVersionMin = Integer.parseInt(recoveryMeasureObject.getString("app_version_min"));
            int appVersionMax = Integer.parseInt(recoveryMeasureObject.getString("app_version_max"));
            RecoveryMeasure measure = new RecoveryMeasure(type, sequenceNumber, ccVersionMin,
                    ccVersionMax, appVersionMin, appVersionMax);
            if (measure.applicableToCurrentInstallation()) {
                measure.registerWithSystem();
                return true;
            }
        } catch (JSONException e) {
            Logger.log(LogTypes.TYPE_ERROR_SERVER_COMMS,
                    "Recovery measure object in heartbeat response not properly formatted: " +
                            e.getMessage());
        } catch (NumberFormatException e) {
            Logger.log(LogTypes.TYPE_ERROR_SERVER_COMMS,
                    "Sequence number or app version in recovery measure response was " +
                            "not a valid number: " + e.getMessage());
        }
        return false;
    }

}

@@ -618,16 +618,530 @@
 ame();%0A%0A
+    private static final String MOCK_RESPONSE = %22%7B%5C%22app_id%5C%22:%5C%22%5C%22,%5C%22recovery_measures%5C%22: %22 +%0A            %22%5B%7B%5C%22sequence_number%5C%22:%5C%221%5C%22, %5C%22type%5C%22:%5C%22clear_data%5C%22, %5C%22cc_version_min%5C%22:%5C%222.36.2%5C%22, %22 +%0A            %22%5C%22cc_version_max%5C%22:%5C%222.45.0%5C%22, %5C%22app_version_min%5C%22:%5C%22200%5C%22, %5C%22app_version_max%5C%22:%5C%221000%5C%22%7D,%22 +%0A            %22%7B%5C%22sequence_number%5C%22:%5C%222%5C%22, %5C%22type%5C%22:%5C%22app_reinstall%5C%22, %5C%22cc_version_min%5C%22:%5C%222.36.2%5C%22, %22 +%0A            %22%5C%22cc_version_max%5C%22:%5C%222.45.0%5C%22, %5C%22app_version_min%5C%22:%5C%22200%5C%22, %5C%22app_version_max%5C%22:%5C%221000%5C%22%7D %5D%7D%22;%0A
 %0A    pub
@@ -1600,84 +1600,304 @@
     
-%7D catch (InterruptedException e) %7B%0A%0A        %7D%0A        // Parse mock response
+    parseResponse(new JSONObject(MOCK_RESPONSE));%0A        %7D catch (InterruptedException e) %7B%0A            // nothing to do%0A        %7D catch (JSONException e) %7B%0A            System.out.println(%22JSONException while parsing mock response: %22 + e.getMessage());%0A            e.printStackTrace();%0A        %7D
 %0A   
@@ -2877,38 +2877,16 @@
 s array 
-in heartbeat response 
 not prop
@@ -4019,16 +4019,30 @@
         
+String.format(
 %22Recover
@@ -4062,30 +4062,8 @@
 ect 
-in heartbeat response 
 not 
@@ -4086,39 +4086,12 @@
 ed: 
-%22 +%0A                           
+%25s%22,
  e.g
@@ -4094,32 +4094,33 @@
  e.getMessage())
+)
 ;%0A        %7D catc
@@ -4226,16 +4226,30 @@
         
+String.format(
 %22Sequenc
@@ -4358,19 +4358,20 @@
 number: 
-%22 +
+%25s%22,
  e.getMe
@@ -4370,32 +4370,33 @@
  e.getMessage())
+)
 ;%0A        %7D%0A    

add parsing of mock response to test