package org.jboss.da.communication.pnc.impl;

import org.jboss.da.common.util.Configuration;
import org.jboss.da.common.util.ConfigurationParseException;
import org.jboss.da.communication.pnc.api.PNCConnector;
import org.jboss.da.communication.pnc.authentication.PNCAuthentication;
import org.jboss.da.communication.pnc.model.BuildConfiguration;
import org.jboss.da.communication.pnc.model.BuildConfigurationCreate;
import org.jboss.da.communication.pnc.model.BuildConfigurationSet;
import org.jboss.da.communication.pnc.model.Product;
import org.jboss.da.communication.pnc.model.Project;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.util.GenericType;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.ws.rs.core.MediaType;

import java.util.Arrays;
import java.util.List;

@ApplicationScoped
public class PNCConnectorImpl implements PNCConnector {

    @Inject
    private PNCAuthentication pncAuthenticate;

    private String pncBaseUrl;

    @Deprecated
    public PNCConnectorImpl() {
    }

    @Inject
    public PNCConnectorImpl(Configuration config) throws ConfigurationParseException {
        pncBaseUrl = config.getConfig().getPncServer() + "/pnc-rest/rest/";
    }

    private ClientRequest getClient(String endpoint, boolean authenticate)
            throws ConfigurationParseException {
        ClientRequest request = new ClientRequest(pncBaseUrl + endpoint);
        request.accept(MediaType.APPLICATION_JSON);

        checkAutentication(authenticate, request);

        return request;
    }

    private void checkAutentication(boolean authenticate, ClientRequest request) {
        // TODO: instead of getting a new token every time, check if existing
        // TODO: token is expired before asking for a new one
        if (authenticate) {
            String token = pncAuthenticate.authenticate();
            request.header("Authorization", "Bearer " + token);
        }
    }

    public ClientRequest getClient(String endpoint) throws ConfigurationParseException {
        return getClient(endpoint, false);
    }

    public ClientRequest getAuthenticatedClient(String endpoint) throws ConfigurationParseException {
        return getClient(endpoint, true);
    }

    @Override
    public List<BuildConfiguration> getBuildConfigurations() throws Exception {
        ClientResponse<BuildConfiguration[]> response = getClient("build-configurations").get(
                BuildConfiguration[].class);
        return Arrays.asList(response.getEntity());
    }

    @Override
    public BuildConfiguration createBuildConfiguration(BuildConfigurationCreate bc)
            throws Exception {
        ClientResponse<BuildConfiguration> response = getClient("build-configurations").body(
                MediaType.APPLICATION_JSON, bc).post(BuildConfiguration.class);
        return response.getEntity();
    }

    @Override
    public BuildConfigurationSet createBuildConfigurationSet(BuildConfigurationSet bcs)
            throws Exception {
        ClientResponse<BuildConfigurationSet> response = getClient("build-configuration-sets")
                .body(MediaType.APPLICATION_JSON, bcs).post(BuildConfigurationSet.class);
        return response.getEntity();
    }

    @Override
    public List<BuildConfigurationSet> getBuildConfigurationSets() throws Exception {
        ClientResponse<BuildConfigurationSet[]> response = getClient("build-configuration-sets")
                .get(BuildConfigurationSet[].class);
        return Arrays.asList(response.getEntity());
    }

    @Override
    public List<Product> getProducts() throws Exception {
        ClientResponse<Product[]> response = getClient("products").get(Product[].class);
        return Arrays.asList(response.getEntity());
    }

    @Override
    public List<Project> getProjects() throws Exception {
        ClientResponse<Project[]> response = getClient("projects").get(Project[].class);
        return Arrays.asList(response.getEntity());
    }

    @Override
    public BuildConfigurationSet findBuildConfigurationSet(int productVersionId,
            List<Integer> buildConfigurationIds) {
        throw new UnsupportedOperationException("Not implemented yet.");
    }

    @Override
    public List<BuildConfiguration> getBuildConfigurations(String scmUrl, String scmRevision)
            throws Exception {
        ClientResponse<List<BuildConfiguration>> response = getClient(
                String.format("build-configurations?q=scmRepoURL=='%s';scmRevision=='%s'", scmUrl,
                        scmRevision)).get(new GenericType<List<BuildConfiguration>>() {});
        return response.getEntity();
    }

}

@@ -843,33 +843,8 @@
 e;%0A%0A
-import java.util.Arrays;%0A
 impo
@@ -2392,32 +2392,37 @@
  ClientResponse%3C
+List%3C
 BuildConfigurati
@@ -2423,18 +2423,17 @@
 guration
-%5B%5D
+%3E
 %3E respon
@@ -2492,16 +2492,37 @@
         
+new GenericType%3CList%3C
 BuildCon
@@ -2531,24 +2531,23 @@
 guration
-%5B%5D.class
+%3E%3E() %7B%7D
 );%0A     
@@ -2552,38 +2552,24 @@
      return 
-Arrays.asList(
 response.get
@@ -2568,33 +2568,32 @@
 onse.getEntity()
-)
 ;%0A    %7D%0A%0A    @Ov
@@ -3409,32 +3409,37 @@
  ClientResponse%3C
+List%3C
 BuildConfigurati
@@ -3443,18 +3443,17 @@
 ationSet
-%5B%5D
+%3E
 %3E respon
@@ -3516,16 +3516,37 @@
    .get(
+new GenericType%3CList%3C
 BuildCon
@@ -3558,24 +3558,23 @@
 ationSet
-%5B%5D.class
+%3E%3E() %7B%7D
 );%0A     
@@ -3579,38 +3579,24 @@
      return 
-Arrays.asList(
 response.get
@@ -3595,33 +3595,32 @@
 onse.getEntity()
-)
 ;%0A    %7D%0A%0A    @Ov
@@ -3707,25 +3707,29 @@
 esponse%3C
+List%3C
 Product
-%5B%5D
+%3E
 %3E respon
@@ -3763,23 +3763,43 @@
 get(
-Product%5B%5D.class
+new GenericType%3CList%3CProduct%3E%3E() %7B%7D
 );%0A 
@@ -3808,38 +3808,24 @@
      return 
-Arrays.asList(
 response.get
@@ -3824,33 +3824,32 @@
 onse.getEntity()
-)
 ;%0A    %7D%0A%0A    @Ov
@@ -3936,25 +3936,29 @@
 esponse%3C
+List%3C
 Project
-%5B%5D
+%3E
 %3E respon
@@ -3992,23 +3992,43 @@
 get(
-Project%5B%5D.class
+new GenericType%3CList%3CProject%3E%3E() %7B%7D
 );%0A 
@@ -4045,22 +4045,8 @@
 urn 
-Arrays.asList(
 resp
@@ -4061,17 +4061,16 @@
 Entity()
-)
 ;%0A    %7D%0A

Refactor PNC connector not to do useless conversion from array to list