package com.theorchard.javaowsassetbulkscript.api;

import java.util.concurrent.TimeUnit;

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import com.theorchard.javaowsassetbulkscript.logic.Asset;

public class ApiConnector {

    private static final int PRODUCTS_IN_CONTENT_TIMEOUT = 10 * 60 * 1000;

	private static String getOwsEnvironment() {
        String url = "qa-";
        String env = System.getenv("USEQA");
        if (env != null && !env.isEmpty()) {
            if (env.equals("false")) {
                url = "";
            }
        }
        return url;
    }

    public static ProductListing getProducts(int vendorId) throws Exception {
        String resourceUrl
            = "https://" + getOwsEnvironment() + "ows-product.theorchard.io/vendor/" + vendorId + "/products?page_limit=100000";
        try {
            RestTemplate restTemplate = new RestTemplate();

            ResponseEntity<ProductListing> response
                    = restTemplate.getForEntity(resourceUrl, ProductListing.class);

            if (response.getStatusCode() != HttpStatus.OK) {
                throw new Exception("Get Releases for Vendor " + vendorId + ": " + response.getStatusCode().toString() + " (" + response.getStatusCode().getReasonPhrase() + ")");
            }

            return response.getBody();
        } catch (Exception e) {
            throw new Exception(resourceUrl+": "+e.getMessage());
        }
    }
    
    public static ProductListing getProductsInContent(int vendorId) throws Exception {
        String resourceUrl
            = "https://" + getOwsEnvironment() + "ows-product.theorchard.io/vendor/" + vendorId + "/products?page_limit=100000&status=in_content";
        try {
        	
        	RestTemplateBuilder builder = new RestTemplateBuilder();
        	RestTemplate restTemplate = builder.setConnectTimeout(PRODUCTS_IN_CONTENT_TIMEOUT).setReadTimeout(PRODUCTS_IN_CONTENT_TIMEOUT).build();
        			
            ResponseEntity<ProductListing> response
                    = restTemplate.getForEntity(resourceUrl, ProductListing.class);

            if (response.getStatusCode() != HttpStatus.OK) {
                throw new Exception("Get Releases for Vendor " + vendorId + ": " + response.getStatusCode().toString() + " (" + response.getStatusCode().getReasonPhrase() + ")");
            }

            return response.getBody();
        } catch (Exception e) {
            throw new Exception(resourceUrl+": "+e.getMessage());
        }
    }

    public static ProductStatus getProductStatus(int productId) throws Exception {
        String resourceUrl
                = "https://"+getOwsEnvironment()+"ows-assets.theorchard.io/asset/product/"+productId;
        try {
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<ProductStatus> response
                    = restTemplate.getForEntity(resourceUrl, ProductStatus.class);

            if (response.getStatusCode() != HttpStatus.OK) {
                throw new Exception("Error when getting Status for Product "+productId+": "+response.getStatusCode().toString()+" ("+response.getStatusCode().getReasonPhrase()+")");
            }

            return response.getBody();
        } catch (Exception e) {
            throw new Exception(resourceUrl+": "+e.getMessage());
        }
    }
    
	public static ProductDocument getProductDocument(int productId) throws Exception {
		String resourceUrl = "https://" + getOwsEnvironment() + "ows-product.theorchard.io/product/" + productId
				+ "/document";
		try {
			RestTemplate restTemplate = new RestTemplate();
			ResponseEntity<ProductDocument> response = restTemplate.getForEntity(resourceUrl, ProductDocument.class);

			if (response.getStatusCode() != HttpStatus.OK) {
				throw new Exception("Error when getting Status for Product " + productId + ": "
						+ response.getStatusCode().toString() + " (" + response.getStatusCode().getReasonPhrase()
						+ ")");
			}

			return response.getBody();
		} catch (Exception e) {
			throw new Exception(resourceUrl + ": " + e.getMessage());
		}
	}

    public static TrackListing getTracks(int productId) throws Exception {
        String resourceUrl
                = "https://"+getOwsEnvironment()+"ows-track.theorchard.io/product/"+productId+"/tracks";

        try {
            RestTemplate restTemplate = new RestTemplate();

            ResponseEntity<TrackListing> response
                    = restTemplate.getForEntity(resourceUrl, TrackListing.class);

            if (response.getStatusCode() != HttpStatus.OK) {
                throw new Exception("Get Tracks for Release " + productId + ": " + response.getStatusCode().toString() + " (" + response.getStatusCode().getReasonPhrase() + ")");
            }
            return response.getBody();
        } catch (Exception e) {
            throw new Exception(resourceUrl+": "+e.getMessage());
        }
    }

    public static UploadToken getUploadToken(int vendorId) throws Exception {
        String resourceUrl
                = "https://"+getOwsEnvironment()+"ows-assets.theorchard.io/upload-token";
        try {
            HttpHeaders headers = new HttpHeaders();

            headers.add("Orchard-User-Id", "oa:1611");
            headers.add("Grass-Account-Id", ""+vendorId);
            headers.add("Grass-Account-Type", "vendor");

            RestTemplate restTemplate = new RestTemplate();

            HttpEntity entity = new HttpEntity(headers);
            ResponseEntity<UploadToken> response
                    = restTemplate.exchange(resourceUrl, HttpMethod.GET, entity, UploadToken.class);

            if (response.getStatusCode() != HttpStatus.OK) {
                throw new Exception("Get UploadToken for Vendor "+vendorId+": "+response.getStatusCode().toString()+" ("+response.getStatusCode().getReasonPhrase()+")");
            }

            return response.getBody();

        } catch (Exception e) {
            throw new Exception(resourceUrl+": "+e.getMessage());
        }
    }

    public static ResponseEntity<String> postAsset(Asset asset, int vendorId) throws Exception {
        String resourceUrl
                = "https://"+getOwsEnvironment()+"ows-assets.theorchard.io/asset";

        try {
            HttpHeaders headers = new HttpHeaders();

            headers.add("Orchard-User-Id", "oa:1611");
            headers.add("Grass-Account-Id", ""+vendorId);
            headers.add("Grass-Account-Type", "vendor");

            RestTemplate restTemplate = new RestTemplate();

            HttpEntity entity = new HttpEntity<Asset>(asset, headers);

            ResponseEntity<String> response = null;

            int attempts = 3;

            while (response == null && attempts > 0) {
                try {
                    response = restTemplate.exchange(resourceUrl, HttpMethod.POST, entity, String.class);
                } catch (RestClientException e) {
                    if (e.getMessage().contains("502 Bad Gateway")) {
                        --attempts;
                        if (attempts == 0) {
                            throw e;
                        } else {
                            TimeUnit.SECONDS.sleep(10);
                        }
                    } else {
                        throw e;
                    }
                }
            }

            if (response.getStatusCode() != HttpStatus.OK) {
                throw new Exception("Post Asset "+asset.getOriginal_filename()+" for Vendor "+vendorId+": "+response.getStatusCode().toString()+" ("+response.getStatusCode().getReasonPhrase()+")");
            }

            return response;

        } catch (Exception e) {
            throw new Exception(resourceUrl+": "+e.getMessage());
        }
    }
}
