package client;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;


/**
 * Class Description - 
 * 
 * @author payne_m
 * 
 * @version $Revision: #3 $  $Date: 2016/06/24 $
 *
 * <!--
 * MedPlus®, Inc., 4690 Parkway Drive, Mason, Ohio 45040, U.S.A.
 * © 1995-2007 MedPlus, Inc. All Rights Reserved.
 *
 * MedPlus, the MedPlus logo, Care360 Hub, the Care360 logo are trademarks, registered trademarks, 
 * or service marks of MedPlus, Inc. in the United States and other countries. MedPlus, Inc., is a 
 * wholly owned subsidiary of Quest Diagnostics Incorporated. Quest, Quest Diagnostics, the associated 
 * logo and all associated Quest Diagnostics marks are the trademarks of Quest Diagnostics Incorporated.
 * -->
 */
public class CompendiumClientTest {
    // CERT environment DOMAIN_URL
    private static final String DOMAIN_URL = "https://cert.hub.care360.com";
    //private static final String DOMAIN_URL = "http://hubvelocity.dev.medplus.com";
    private static final String REQUEST_URL = "/rest/compendiums/v1/requestCompendiums";
    // Substitute this credentials with CERT username and password
    private static final String USER_NAME = "CompendiumManagement";
    private static final String USER_PASSWORD = "passw0rd";

    private static final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder()
            .credentials(USER_NAME, USER_PASSWORD).build();

    public static void main(String[] args) {
        CompendiumClientTest clientTest = new CompendiumClientTest();
        TestCompendiumsLinksResponse links = null;

        try {
            Object object = clientTest.getRequest();
            if (object instanceof TestCompendiumsLinksResponse) {
                links = (TestCompendiumsLinksResponse) object;

                // Retrieve the Full Files
                if (links.getFullFileLinks() != null && links.getFullFileLinks().length > 0) {
                    System.out.println("Full File Transaction: " + links.getTransactionId());
                    for (TestCompendiumsLinks link : links.getFullFileLinks()) {
                        InputStream stream = clientTest.getFileStream(link.getRetrieveURI());
                        clientTest.writeToFile(stream, link.getFileName());

                        // After the file has been retrieved we need to confirm
                        // that it was received by an Ack
                        clientTest.ackFile(link.getAckURI());
                    }
                } else {
                    System.out.println("There are no new Full Files available for download at this time.");
                }

                // Retrieve the current Delta Files
                if (links.getDeltaFileLinks() != null && links.getDeltaFileLinks().length > 0) {
                    System.out.println("Delta File Transaction: " + links.getTransactionId());
                    for (TestCompendiumsLinks deltaLink : links.getDeltaFileLinks()){
                	InputStream stream = clientTest.getFileStream(deltaLink.getRetrieveURI());
                        clientTest.writeToFile(stream, deltaLink.getFileName());
                        
                        // After the file has been retrieved we need to confirm that it was received by an Ack
                        clientTest.ackFile(deltaLink.getAckURI());                	
                    }                    
                } else {
                    System.out.println("There are no new Delta Files available for download at this time.");
                }

                // Retrieve the previous Delta Files
                if (links.getPreviouslyNotifiedDeltasLinks() != null
                        && links.getPreviouslyNotifiedDeltasLinks().length > 0) {
                    for (TestCompendiumsLinks link : links.getPreviouslyNotifiedDeltasLinks()) {
                        System.out.println("Previously Notified Delta File Transaction: "
                                + link.getRelatedTransactionId());

                        InputStream stream = clientTest.getFileStream(link.getRetrieveURI());
                        clientTest.writeToFile(stream, link.getFileName());

                        // After the file has been retrieved we need to confirm
                        // that it was received by an Ack
                        clientTest.ackFile(link.getAckURI());
                    }
                } else {
                    System.out.println("There are no previous Delta Files available for download at this time.");
                }

                // Retrieve the previous Full Files
                if (links.getPreviouslyNotifiedFullFileLinks() != null && links.getPreviouslyNotifiedFullFileLinks().length > 0) {
                    for (TestCompendiumsLinks link : links.getPreviouslyNotifiedFullFileLinks()) {
                        System.out.println("Previously Notified Full File Transaction: " + link.getRelatedTransactionId());

                        InputStream stream = clientTest.getFileStream(link.getRetrieveURI());
                        clientTest.writeToFile(stream, link.getFileName());
                        
                        // After the file has been retrieved we need to confirm that it was received by an Ack
                        clientTest.ackFile(link.getAckURI());
                    }
                } else {
                    System.out.println("There are no previous Full Files available for download at this time.");
                }

                if (links.getErrorMessage() != null && links.getErrorMessage().trim().length() > 0) {
                    System.out.println("There was an error reported by the server: " + links.getErrorMessage());
                }
            } else {
                System.out.println("There was an error reported by the server: " + (String) object);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Object getRequest() throws IOException {
        Client client = ClientBuilder.newClient();
        client.register(feature);
        client.register(JacksonJsonProvider.class);
        WebTarget target = client.target(DOMAIN_URL + REQUEST_URL);

        System.out.println("Requesting the list of available files.");

        // Request a list of compendium files that can be retrieved in JSON
        // format
        TestCompendiumsLinksResponse links = null;
        Response response = target.request().get();
        if (response.getStatus() == 200 || response.getStatus() == 500) {
            links = response.readEntity(TestCompendiumsLinksResponse.class);
        } else {
            return response.readEntity(String.class);
        }

        return links;
    }

    public InputStream getFileStream(String urlPath) throws IOException {
        Client client = ClientBuilder.newClient();
        client.register(feature);
        client.register(JacksonJsonProvider.class);
        WebTarget target = client.target(DOMAIN_URL + urlPath);

        // Retrieve a given file and stream the response to a file
        InputStream stream = null;
        Response response = target.request().get();
        if (response.getStatus() == 200) {
            stream = response.readEntity(InputStream.class);
        } else {
            System.out.println("Error communicating to server: " + response.readEntity(String.class));
        }

        return stream;
    }

    public Object ackFile(String urlPath) throws IOException {
        Client client = ClientBuilder.newClient();
        client.register(feature);
        client.register(JacksonJsonProvider.class);
        WebTarget target = client.target(DOMAIN_URL + urlPath);

        System.out.println("Acking the file that was just pulled down.");

        // Ack a retrieved file
        TestcompendiumsAckResponse links = null;
        Response response = target.request().get();
        if (response.getStatus() == 200) {
            links = response.readEntity(TestcompendiumsAckResponse.class);
        } else {
            return response.readEntity(String.class);
        }

        return links;
    }

    private void writeToFile(InputStream stream, String fileName) throws IOException {
        File file = new File(fileName);
        System.out.println("Pulling the file: " + fileName);
        FileOutputStream fo = new FileOutputStream(file);

        if (stream != null) {
            while (true) {
                int data = stream.read();
                if (data == -1) {
                    break;
                }
                fo.write(data);
            }
        }

        stream.close();
        fo.flush();
        fo.close();
    }
}

