package org.bandie.yipanic;

import android.content.Context;
import android.util.Log;
import android.view.View;

import androidx.security.crypto.EncryptedSharedPreferences;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.google.android.material.snackbar.Snackbar;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.security.GeneralSecurityException;

class Command {
  private final Snackbar sbOk, sbNotSet, sbAccessDenied, sbFailed, sbNoServer;
  private String server, k, s;

  Command(View view, Context context) {
    this.sbOk = Snackbar.make(view, "Sent. :)", 3000);
    this.sbNotSet = Snackbar.make(view, "Command not set. :/", 3000);
    this.sbAccessDenied = Snackbar.make(view, "Access denied. >:(", 3000);
    this.sbFailed = Snackbar.make(view, "Failed. :C", 3000);
    this.sbNoServer = Snackbar.make(view, "No server configured! :o", 3000);

    try {
      EncryptedSharedPreferences sharedPreferences = (EncryptedSharedPreferences) EncryptedSharedPreferences
          .create(
              "Yipanic",
              "Yipanic",
              context,
              EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
              EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
          );
      this.server = sharedPreferences.getString("server", null);
      this.k = sharedPreferences.getString("key", null);
      this.s = sharedPreferences.getString("secret", null);
    } catch (IOException | GeneralSecurityException e) {
      if (e.getMessage() != null)
        Log.e("Yipanic", e.getMessage());
      else
        Log.e("Yipanic", "[ No exception message ]");
    }
  }

  private JsonObjectRequest requestHandler(String cmd) {
    JSONObject json = new JSONObject();
    try {
      json.put("key", this.k);
      json.put("secret", this.s);
      json.put("cmd", cmd);
    } catch (JSONException e) {
      if (e.getMessage() != null)
        Log.e("Yipanic", e.getMessage());
      else
        Log.e("Yipanic", "[ No exception message ]");
    }
    if (this.server == null) {
      sbNoServer.show();
      return null;
    }
    return new JsonObjectRequest
        (Request.Method.POST, this.server, json, new Response.Listener<JSONObject>() {

          @Override
          public void onResponse(JSONObject response) {
            try {
              if (response.getBoolean("access")) {
                switch (response.getInt("error")) {
                  case 0:
                    sbOk.show();
                    break;
                  case 1:
                    sbNotSet.show();
                    break;
                  case 2:
                    //Password required
                    break;
                  case 4:
                    //Password OK
                    break;
                }
              } else {
                sbAccessDenied.show();
              }

            } catch (JSONException e) {
              if (e.getMessage() != null)
                Log.e("Yip", e.getMessage());
              else
                Log.e("Yip", "[ No exception message ]");
              sbFailed.show();
            }
          }
        }, new Response.ErrorListener() {

          @Override
          public void onErrorResponse(VolleyError e) {
            if (e.getMessage() != null)
              Log.e("Yip", e.getMessage());
            else
              Log.e("Yip", "[ No exception message ]");
            sbFailed.show();
          }
        });
  }

  JsonObjectRequest lock() {
    return requestHandler("lock");
  }

  JsonObjectRequest shutdown() {
    return requestHandler("shutdown");
  }

  JsonObjectRequest panic() {
    return requestHandler("panic");
  }

  JsonObjectRequest infraShutdown() {
    return requestHandler("infraShutdown");
  }

  JsonObjectRequest infraPanic() {
    return requestHandler("infraPanic");
  }

}
