/*
 * Copyright (C) 2007-2014, GoodData(R) Corporation. All rights reserved.
 */
package com.gooddata;

import com.gooddata.account.AccountService;
import com.gooddata.dataset.DatasetService;
import com.gooddata.gdc.DataStoreService;
import com.gooddata.gdc.GdcService;
import com.gooddata.http.client.GoodDataHttpClient;
import com.gooddata.http.client.LoginSSTRetrievalStrategy;
import com.gooddata.http.client.SSTRetrievalStrategy;
import com.gooddata.md.MetadataService;
import com.gooddata.model.ModelService;
import com.gooddata.project.ProjectService;
import org.apache.http.HttpHost;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;

import static java.util.Collections.singletonMap;

/**
 */
public class GoodData {

    private static final String PROTOCOL = "https";
    private static final int PORT = 443;
    private static final String HOSTNAME = "secure.gooddata.com";

    private final RestTemplate restTemplate;
    private final HttpClientBuilder httpClientBuilder;
    private final String login;
    private final String password;
    private AccountService accountService;
    private ProjectService projectService;
    private MetadataService metadataService;
    private ModelService modelService;
    private GdcService gdcService;
    private DataStoreService dataStoreService;
    private DatasetService datasetService;

    public GoodData(String login, String password) {
        this(login, password, HOSTNAME);
    }

    public GoodData(String hostname, String login, String password) {
        this.login = login;
        this.password = password;
        final HttpHost host = new HttpHost(hostname, PORT, PROTOCOL);

        httpClientBuilder = HttpClientBuilder.create();
        final CloseableHttpClient httpClient = httpClientBuilder.build();
        final SSTRetrievalStrategy strategy = new LoginSSTRetrievalStrategy(httpClient, host, login, password);

        final HttpClient client = new GoodDataHttpClient(httpClient, strategy);

        final UriPrefixingClientHttpRequestFactory factory = new UriPrefixingClientHttpRequestFactory(
                new HttpComponentsClientHttpRequestFactory(client), hostname, PORT, PROTOCOL);
        restTemplate = new RestTemplate(factory);
        restTemplate.setInterceptors(Arrays.<ClientHttpRequestInterceptor>asList(
                new HeaderAddingRequestInterceptor(singletonMap("Accept", MediaType.APPLICATION_JSON_VALUE))));

        initServices();
    }

    public void logout() {
        getAccountService().logout();
    }

    public ProjectService getProjectService() {
        return projectService;
    }

    public AccountService getAccountService() {
        return accountService;
    }

    public MetadataService getMetadataService() {
        return metadataService;
    }

    public ModelService getModelService() {
        return modelService;
    }

    public GdcService getGdcService() {
        return gdcService;
    }

    public DataStoreService getDataStoreService() {
        return dataStoreService;
    }

    public DatasetService getDatasetService() {
        return datasetService;
    }

    private void initServices() {
        accountService = new AccountService(restTemplate);
        projectService = new ProjectService(restTemplate, getAccountService());
        metadataService = new MetadataService(restTemplate);
        modelService = new ModelService(restTemplate);
        gdcService = new GdcService(restTemplate);
        dataStoreService = new DataStoreService(httpClientBuilder, getGdcService(), login, password);
        datasetService = new DatasetService(restTemplate, getDataStoreService());
    }
}

@@ -1273,169 +1273,8 @@
 nal 
-RestTemplate restTemplate;%0A    private final HttpClientBuilder httpClientBuilder;%0A    private final String login;%0A    private final String password;%0A    private 
 Acco
@@ -1312,16 +1312,22 @@
 private 
+final 
 ProjectS
@@ -1361,16 +1361,22 @@
 private 
+final 
 Metadata
@@ -1412,16 +1412,22 @@
 private 
+final 
 ModelSer
@@ -1457,16 +1457,22 @@
 private 
+final 
 GdcServi
@@ -1494,24 +1494,30 @@
     private 
+final 
 DataStoreSer
@@ -1551,16 +1551,22 @@
 private 
+final 
 DatasetS
@@ -1772,186 +1772,869 @@
     
-this.login = login;%0A        this.password = password;%0A        final HttpHost host = new HttpHost(hostname, PORT, PROTOCOL);%0A%0A
+final HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();%0A        final RestTemplate restTemplate = createRestTemplate(hostname, login, password, httpClientBuilder);%0A%0A        accountService = new AccountService(restTemplate);%0A        projectService = new ProjectService(restTemplate, accountService);%0A        metadataService = new MetadataService(restTemplate);%0A        modelService = new ModelService(restTemplate);%0A        gdcService = new GdcService(restTemplate);%0A 
        
- httpClientBuilder = HttpClientBuilder.create(
+dataStoreService = new DataStoreService(httpClientBuilder, gdcService, login, password);%0A        datasetService = new DatasetService(restTemplate, dataStoreService);%0A    %7D%0A%0A    private RestTemplate createRestTemplate(String hostname, String login, String password, HttpClientBuilder httpClientBuilder) %7B%0A        final HttpHost host = new HttpHost(hostname, PORT, PROTOCOL
 );%0A 
@@ -3098,32 +3098,51 @@
 TOCOL);%0A        
+final RestTemplate 
 restTemplate = n
@@ -3361,25 +3361,24 @@
 UE))));%0A
-%0A
         
 initServ
@@ -3369,30 +3369,35 @@
         
-initServices()
+return restTemplate
 ;%0A    %7D%0A
@@ -4066,536 +4066,6 @@
  %7D%0A%0A
-    private void initServices() %7B%0A        accountService = new AccountService(restTemplate);%0A        projectService = new ProjectService(restTemplate, getAccountService());%0A        metadataService = new MetadataService(restTemplate);%0A        modelService = new ModelService(restTemplate);%0A        gdcService = new GdcService(restTemplate);%0A        dataStoreService = new DataStoreService(httpClientBuilder, getGdcService(), login, password);%0A        datasetService = new DatasetService(restTemplate, getDataStoreService());%0A    %7D%0A
 %7D%0A

make services final