package org.bigdata.yelp.yelpreco;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Properties;

import org.bigdata.yelp.util.Property;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;

public class RecoLister {

	private AWSCredentials credentials;
	public static AmazonS3Client s3Client = null;
	public static String bucketName = "yelpreco";

	public RecoLister() {
		try {
			init();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	private void init() throws ClassNotFoundException {
		try {
			final Properties prop = Property.getPropInstance();
			// read AWS credentials
			/*credentials = new PropertiesCredentials(
					RecoLister.class
							.getResourceAsStream("AwsCredentials.properties"));*/
			credentials = new AWSCredentials() {
				
				public String getAWSSecretKey() {
					return prop.getProperty("SECRET_KEY");
				}
				
				public String getAWSAccessKeyId() {
					return prop.getProperty("ACCESS_KEY");
				}
			};
			
			if (s3Client == null)
				s3Client = new AmazonS3Client(credentials);
			// System.out.println("Creating S3 client");

		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}

	public ArrayList<String> getRecos(String userId) throws IOException {

		ArrayList<String> recoList = new ArrayList<String>();
		String prefix = "yelp_output/" + userId + "/prediction/";
//		String prefix = "";
		String s3ObjectName = "";
		try {
			ObjectListing objectListing = s3Client
					.listObjects(new ListObjectsRequest()
							.withBucketName(bucketName).withPrefix(prefix));
			boolean skipFirst = true;
			for (S3ObjectSummary objectSummary : objectListing
					.getObjectSummaries()) {
				if(skipFirst) {
					skipFirst = false;
					continue;
				}
				System.out.println("Object is: " + objectSummary.getKey().toString());
				s3ObjectName = objectSummary.getKey().toString();
				break;
			}
			System.out.println("Downloading an object..");
			S3Object s3object = s3Client.getObject(new GetObjectRequest(
					bucketName, s3ObjectName));
			System.out.println("Content-Type: "
					+ s3object.getObjectMetadata().getContentType());
//			displayTextInputStream(s3object.getObjectContent());

		} catch (AmazonServiceException ase) {
			printAmazonServiceException(ase);
		} catch (AmazonClientException ace) {
			printAmazonClientException(ace);
		}

		// TODO (optional): Calculate the distance from the user using lat and
		// long

		// TODO: Form and return the reco list

		return null;
	}

	private void displayTextInputStream(InputStream input) throws IOException {
		// Read one text line at a time and display.
		BufferedReader reader = new BufferedReader(new InputStreamReader(input));
		while (true) {
			String line = reader.readLine();
			if (line == null)
				break;

			System.out.println("    " + line);
		}
		System.out.println();
	}

	private void printAmazonServiceException(AmazonServiceException ase) {
		System.out
				.println("Caught an AmazonServiceException, which means your request made it "
						+ "to Amazon S3, but was rejected with an error response for some reason.");
		System.out.println("Error Message:    " + ase.getMessage());
		System.out.println("HTTP Status Code: " + ase.getStatusCode());
		System.out.println("AWS Error Code:   " + ase.getErrorCode());
		System.out.println("Error Type:       " + ase.getErrorType());
		System.out.println("Request ID:       " + ase.getRequestId());
	}

	private void printAmazonClientException(AmazonClientException ace) {
		System.out
				.println("Caught an AmazonClientException, which means the client encountered "
						+ "a serious internal problem while trying to communicate with S3, "
						+ "such as not being able to access the network.");
		System.out.println("Error Message: " + ace.getMessage());
	}
	
	public static void main(String args[]) {
		String userId = "kJyR4gT1pfCcNjEY9-YMoQ";
		RecoLister recoLister = new RecoLister();
		try {
			recoLister.getRecos(userId);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
