package me.devsaki.hentoid.util;

import androidx.documentfile.provider.DocumentFile;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

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

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import okhttp3.Call;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import timber.log.Timber;

/**
 * Created by avluis on 06/05/2016.
 * JSON related utility class
 */
public class JsonHelper {

    public static String serializeToJson(Object o) {
        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
        // convert java object to JSON format, and return as a JSON formatted string
        return gson.toJson(o);
    }

    public static <K> File saveJson(K object, File dir) throws IOException {
        File file = new File(dir, Consts.JSON_FILE_NAME_V2);
        String json = serializeToJson(object);
        try (OutputStream output = FileHelper.getOutputStream(file)) {
            if (output != null) {
                // build
                byte[] bytes = json.getBytes();
                // write
                output.write(bytes);
                FileHelper.sync(output);
                output.flush();
            } else {
                Timber.w("JSON file creation failed for %s", file.getPath());
            }
        }
        return file;
    }

    public static <K> void saveJson(K object, @Nonnull DocumentFile file) throws IOException {
        try (OutputStream output = FileHelper.getOutputStream(file)) {
            if (output != null) {
                String json = serializeToJson(object);
                // build
                byte[] bytes = json.getBytes();
                // write
                output.write(bytes);
                FileHelper.sync(output);
                output.flush();
            } else {
                Timber.w("JSON file creation failed for %s", file.getUri());
            }
        } catch (FileNotFoundException e) {
            Timber.e(e);
        }
    }

    public static <T> T jsonToObject(File f, Class<T> type) throws IOException {
        StringBuilder json = new StringBuilder();
        String sCurrentLine;
        try (BufferedReader br = new BufferedReader(new FileReader(f))) {
            while ((sCurrentLine = br.readLine()) != null) {
                json.append(sCurrentLine);
            }
        }
        // Ignore

        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
        return gson.fromJson(json.toString(), type);
    }

    @Nullable
    synchronized static JSONObject jsonReader(String jsonURL) throws IOException {
        try {
            Request request = new Request.Builder()
                    .url(jsonURL)
                    .addHeader("User-Agent", Consts.USER_AGENT)
                    .addHeader("Data-type", "application/json")
                    .build();

            Call okHttpCall = OkHttpClientSingleton.getInstance().newCall(request);

            Response okHttpResponse = okHttpCall.execute();

            int responseCode = okHttpResponse.code();
            Timber.d("HTTP Response: %s", responseCode);
            if (404 == responseCode) {
                return null;
            }

            ResponseBody body = okHttpResponse.body();
            if (body != null) {
                return new JSONObject(readInputStream(body.byteStream()));
            } else {
                Timber.e("JSON request body is null");
                return null;
            }
        } catch (JSONException e) {
            Timber.e(e, "JSON file not properly formatted");
        }

        return null;
    }

    private static String readInputStream(InputStream stream) throws IOException {
        StringBuilder builder = new StringBuilder(stream.available());
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream,
                Charset.forName("UTF-8")));
        String line = reader.readLine();

        while (line != null) {
            builder.append(line);
            line = reader.readLine();
        }
        reader.close();

        return builder.toString();
    }
}

@@ -150,68 +150,8 @@
 r;%0A%0A
-import org.json.JSONException;%0Aimport org.json.JSONObject;%0A%0A
 impo
@@ -310,284 +310,56 @@
 .io.
-InputStream;%0Aimport java.io.InputStreamReader;%0Aimport java.io.OutputStream;%0Aimport java.nio.charset.Charset;%0A%0Aimport javax.annotation.Nonnull;%0Aimport javax.annotation.Nullable;%0A%0Aimport okhttp3.Call;%0Aimport okhttp3.Request;%0Aimport okhttp3.Response;%0Aimport okhttp3.ResponseBody;
+OutputStream;%0A%0Aimport javax.annotation.Nonnull;%0A
 %0Aimp
@@ -2586,1621 +2586,7 @@
    %7D
-%0A%0A    @Nullable%0A    synchronized static JSONObject jsonReader(String jsonURL) throws IOException %7B%0A        try %7B%0A            Request request = new Request.Builder()%0A                    .url(jsonURL)%0A                    .addHeader(%22User-Agent%22, Consts.USER_AGENT)%0A                    .addHeader(%22Data-type%22, %22application/json%22)%0A                    .build();%0A%0A            Call okHttpCall = OkHttpClientSingleton.getInstance().newCall(request);%0A%0A            Response okHttpResponse = okHttpCall.execute();%0A%0A            int responseCode = okHttpResponse.code();%0A            Timber.d(%22HTTP Response: %25s%22, responseCode);%0A            if (404 == responseCode) %7B%0A                return null;%0A            %7D%0A%0A            ResponseBody body = okHttpResponse.body();%0A            if (body != null) %7B%0A                return new JSONObject(readInputStream(body.byteStream()));%0A            %7D else %7B%0A                Timber.e(%22JSON request body is null%22);%0A                return null;%0A            %7D%0A        %7D catch (JSONException e) %7B%0A            Timber.e(e, %22JSON file not properly formatted%22);%0A        %7D%0A%0A        return null;%0A    %7D%0A%0A    private static String readInputStream(InputStream stream) throws IOException %7B%0A        StringBuilder builder = new StringBuilder(stream.available());%0A        BufferedReader reader = new BufferedReader(new InputStreamReader(stream,%0A                Charset.forName(%22UTF-8%22)));%0A        String line = reader.readLine();%0A%0A        while (line != null) %7B%0A            builder.append(line);%0A            line = reader.readLine();%0A        %7D%0A        reader.close();%0A%0A        return builder.toString();%0A    %7D
 %0A%7D%0A

Remove obsolete methods