package ge.edu.freeuni.sdp.iot.service.camera_object_recognizer.proxy;

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.vision.v1.Vision;
import com.google.api.services.vision.v1.VisionScopes;
import com.google.api.services.vision.v1.model.AnnotateImageRequest;
import com.google.api.services.vision.v1.model.AnnotateImageResponse;
import com.google.api.services.vision.v1.model.BatchAnnotateImagesRequest;
import com.google.api.services.vision.v1.model.BatchAnnotateImagesResponse;
import com.google.api.services.vision.v1.model.EntityAnnotation;
import com.google.api.services.vision.v1.model.Feature;
import com.google.api.services.vision.v1.model.Image;
import com.google.common.collect.ImmutableList;
import ge.edu.freeuni.sdp.iot.service.camera_object_recognizer.model.ServiceState;

import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;

public class GoogleApiServiceProxy {

    private static final String APPLICATION_NAME = "FreeUniSDP-IotCameraObjectRecognizer/1.0";

    private static final double TRUST_THRESHOLD = 80.;

    private final ServiceState state;


    public GoogleApiServiceProxy(ServiceState state) {
        this.state = state;
    }

    public List<String> getObjectList(byte[] imageData, int maxResults) throws IOException, GeneralSecurityException {
        List<String> objects = new ArrayList<>();
        for (EntityAnnotation label : labelImage(imageData, maxResults)) {
            if (label.getScore() >= TRUST_THRESHOLD) {
                objects.add(label.getDescription());
            }
        }

        return objects;
    }

    private List<EntityAnnotation> labelImage(byte[] imageData, int maxResults) throws IOException, GeneralSecurityException {
        AnnotateImageRequest request =
                new AnnotateImageRequest()
                        .setImage(new Image().encodeContent(imageData))
                        .setFeatures(ImmutableList.of(
                                new Feature()
                                        .setType("LABEL_DETECTION")
                                        .setMaxResults(maxResults)));
        Vision.Images.Annotate annotate = getVisionService()
                .images()
                .annotate(new BatchAnnotateImagesRequest().setRequests(ImmutableList.of(request)));

        BatchAnnotateImagesResponse batchResponse = annotate.execute();
        assert batchResponse.getResponses().size() == 1;
        AnnotateImageResponse response = batchResponse.getResponses().get(0);
        if (response.getLabelAnnotations() == null) {
            throw new IOException(
                    response.getError() != null
                            ? response.getError().getMessage()
                            : "Unknown error getting image annotations");
        }

        return response.getLabelAnnotations();
    }

    private static Vision getVisionService() throws IOException, GeneralSecurityException {
        GoogleCredential credential = GoogleCredential.getApplicationDefault().createScoped(VisionScopes.all());
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();

        return new Vision.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, credential)
                .setApplicationName(APPLICATION_NAME)
                .build();
    }
}

@@ -207,16 +207,76 @@
 nsport;%0A
+import com.google.api.client.http.javanet.NetHttpTransport;%0A
 import c
@@ -467,485 +467,15 @@
 .v1.
-VisionScopes;%0Aimport com.google.api.services.vision.v1.model.AnnotateImageRequest;%0Aimport com.google.api.services.vision.v1.model.AnnotateImageResponse;%0Aimport com.google.api.services.vision.v1.model.BatchAnnotateImagesRequest;%0Aimport com.google.api.services.vision.v1.model.BatchAnnotateImagesResponse;%0Aimport com.google.api.services.vision.v1.model.EntityAnnotation;%0Aimport com.google.api.services.vision.v1.model.Feature;%0Aimport com.google.api.services.vision.v1.model.Image
+model.*
 ;%0Aim
@@ -636,119 +636,8 @@
 on;%0A
-import java.io.PrintStream;%0Aimport java.nio.file.Files;%0Aimport java.nio.file.Path;%0Aimport java.nio.file.Paths;%0A
 impo
@@ -921,16 +921,248 @@
 = 80.;%0A%0A
+    private static final String GOOGLE_CLIENT_ID = %22GOOGLE_CLIENT_ID%22;%0A%0A    private static final String GOOGLE_CLIENT_SECRET = %22GOOGLE_CLIENT_SECRET%22;%0A%0A    private static final String GOOGLE_REFRESH_TOKEN = %22GOOGLE_REFRESH_TOKEN%22;%0A%0A
     priv
@@ -3049,368 +3049,1314 @@
     
-GoogleCredential credential = GoogleCredential.getApplicationDefault().createScoped(VisionScopes.all());%0A        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();%0A%0A        return new Vision.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, credential)%0A                .setApplicationName(APPLICATION_NAME)%0A                .build()
+JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();%0A        NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();%0A        GoogleCredential credential = getCredentials(jsonFactory, httpTransport);%0A%0A        return new Vision.Builder(httpTransport, jsonFactory, credential)%0A                .setApplicationName(APPLICATION_NAME)%0A                .build();%0A    %7D%0A%0A    private static GoogleCredential getCredentials(JsonFactory jsonFactory, NetHttpTransport httpTransport) throws IOException %7B%0A        // return GoogleCredential.getApplicationDefault().createScoped(VisionScopes.all());%0A        String clientId = getEnv(GOOGLE_CLIENT_ID);%0A        String clientSecret = getEnv(GOOGLE_CLIENT_SECRET);%0A        String refreshToken = getEnv(GOOGLE_REFRESH_TOKEN);%0A%0A        return new GoogleCredential.Builder()%0A                .setJsonFactory(jsonFactory)%0A                .setTransport(httpTransport)%0A                .setClientSecrets(clientId, clientSecret)%0A                .build()%0A                .setRefreshToken(refreshToken);%0A    %7D%0A%0A    private static String getEnv(String envVarName) throws IOException %7B%0A        String envVar = System.getenv(envVarName);%0A        if (envVar == null)%0A            throw new IOException(envVarName + %22is not specified.%22);%0A%0A        return envVar
 ;%0A  

Update GoogleApiServiceProxy. Building credentials from envvars