package com.test.ocr;

import android.content.Context;
import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONArray;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.Response;


public class HWOcrClientToken {
    private String domainName = null;
    private String userName = null;
    private String password = null;
    private String region = null;
    private String endPoint = null;
    private String ocrToken = null;
    private Context context;
    private static CountDownLatch latch = new CountDownLatch(1);


    public HWOcrClientToken(Context context, String domainName, String userName, String password, String region, String endPoint) {
        if (TextUtils.isEmpty(domainName)) {
            Toast.makeText(context, "domainName cannot be empty", Toast.LENGTH_LONG).show();
            return;
        }
        if (TextUtils.isEmpty(userName)) {
            Toast.makeText(context, "userName cannot be empty", Toast.LENGTH_LONG).show();
            return;
        }
        if (TextUtils.isEmpty(password)) {
            Toast.makeText(context, "password cannot be empty", Toast.LENGTH_LONG).show();
            return;
        }
        if (TextUtils.isEmpty(region)) {
            Toast.makeText(context, "region cannot be empty", Toast.LENGTH_LONG).show();
            return;
        }

        if (TextUtils.isEmpty(endPoint)) {
            Toast.makeText(context, "endPoint is not empty", Toast.LENGTH_LONG).show();
            return;
        }
        this.domainName = domainName;
        this.userName = userName;
        this.password = password;
        this.region = region;
        this.endPoint = endPoint;
        this.context = context;
    }

    //  set required parameters to request the token of ocr service
    private String requestBody() {
        JSONObject auth = new JSONObject();
        JSONObject identity = new JSONObject();
        JSONArray methods = new JSONArray();
        methods.add("password");
        identity.put("methods", methods);
        JSONObject pw = new JSONObject();
        JSONObject user = new JSONObject();
        user.put("name", userName);
        user.put("password", password);
        JSONObject domain = new JSONObject();
        domain.put("name", domainName);
        user.put("domain", domain);
        pw.put("user", user);
        identity.put("password", pw);
        JSONObject scope = new JSONObject();
        JSONObject scopeProject = new JSONObject();
        scopeProject.put("name", region);
        scope.put("project", scopeProject);
        auth.put("identity", identity);
        auth.put("scope", scope);
        JSONObject params = new JSONObject();
        params.put("auth", auth);
        return params.toJSONString();
    }

    /**
     * return ocr token
     */
    private String getToken() {
        if (ocrToken != null) return ocrToken;
        new Thread() {
            @Override
            public void run() {
                super.run();
                String requestBodyJsonStr = requestBody();
                String url = "https://iam." + region + ".myhuaweicloud.com/v3/auth/tokens";
                OkHttpClient okHttpClient = new OkHttpClient();
                RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), requestBodyJsonStr);
                okhttp3.Request request = new okhttp3.Request.Builder()
                        .url(url)
                        .post(requestBody)
                        .build();
                Call call = okHttpClient.newCall(request);
                call.enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        latch.countDown();
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        ocrToken = response.header("X-Subject-Token").toString();
                        Log.d("onResponse", "token = " + ocrToken);
                        latch.countDown();
                    }
                });

            }
        }.start();
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return ocrToken;
    }

    private void refreshToken() {
        ocrToken = null;
        ocrToken = getToken();
    }

    /**
     * request ocr service
     *
     * @param uri      ocr request uri
     * @param bit      detective image
     * @param option   optional parameters
     * @param callback the callback of success or Failure
     */
    public void requestOcrTokenService(String uri, Bitmap bit, Map<String, String> option, Callback callback) {
        if (TextUtils.isEmpty(uri)) {
            Toast.makeText(context, "uri cannot be empty", Toast.LENGTH_LONG).show();
            return;
        }
        if (HWOcrClientUtils.isEmptyBitmap(bit)) {
            Toast.makeText(context, " Bitmap bit cannot be empty", Toast.LENGTH_LONG).show();
            return;
        }
        ocrToken = getToken();
        String fileBase64Str = HWOcrClientUtils.BitmapStrByBase64(bit);//
        JSONObject requestBodyJsonStr = new JSONObject();
        requestBodyJsonStr.put("image", fileBase64Str);
        if (option != null) {
            for (String k : option.keySet()) {
                requestBodyJsonStr.put(k, option.get(k));
            }
        }
        OkHttpClient okHttpClient = new OkHttpClient();

        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), requestBodyJsonStr.toJSONString());
        okhttp3.Request request = new okhttp3.Request.Builder()
                .url("https://" + endPoint + uri)
                .post(requestBody)
                .addHeader("X-Auth-Token", ocrToken)
                .build();

        Call call = okHttpClient.newCall(request);
        call.enqueue(callback);
    }
}
