
package cc.glsn.v15.gp.imagenest;

import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.List;
import java.util.LinkedList;
import java.io.File;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;

import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ObjectMetadata;

import java.util.logging.Logger;
import java.util.logging.Level;



public class S3Sync
{
	private static final String SRC_DIR="/home/clash/1209k.com/www/nest/images";
	private static final String BUCKET="imagenest";
	private static final String AWS_ID="AKIAID53GY7F3RMNREGQ";
	private static final String AWS_KEY="DELETED";

	public static void main(String args[])
		throws Exception
	{
		Logger.getLogger("").setLevel(Level.WARNING);
		new S3Sync();

	}

	private TreeMap<String, File> local_files;
	private TreeMap<String, S3ObjectSummary> s3objs;

	private TreeSet<String> to_delete;
	private TreeSet<String> to_upload;


	public S3Sync()
		throws Exception
	{
		AWSCredentials creds = new BasicAWSCredentials(AWS_ID, AWS_KEY);
		AmazonS3Client svc = new AmazonS3Client(creds);

		
		List<S3ObjectSummary> objs = listAllObjects(svc);

		local_files = new TreeMap<String, File>();
		populateFileTree(new File(SRC_DIR), "", local_files);

		s3objs=new TreeMap<String, S3ObjectSummary>();		

		for(S3ObjectSummary obj : objs)
		{
			s3objs.put(obj.getKey(), obj);

			//System.out.println("s3: " + obj.getKey());

			//S3Object details = svc.getObjectDetails(bucket, obj.getKey());
			//printInfo(details);
			//deleteIfNotImage(details, svc, bucket);
		}

		for(String s : local_files.keySet())
		{
			//System.out.println("local: " + s);
		}
		buildUpdateSet();

		if (local_files.size() < 200)
		{
			System.out.println("Local file list sanity check failed. Aborting.");
			return;
		}



		doDelete(svc);
		doUpload(svc);

	}

	private List<S3ObjectSummary> listAllObjects(AmazonS3Client svc)
	{
		List<S3ObjectSummary> lst = new LinkedList<S3ObjectSummary>();
		
		String next = null;
		do
		{
			ListObjectsRequest r = new ListObjectsRequest();
			r.setBucketName(BUCKET);
			r.setMarker(next);
			ObjectListing ol = svc.listObjects(r);
			for(S3ObjectSummary o : ol.getObjectSummaries())
			{
				lst.add(o);
			}


			next= ol.getNextMarker();


		}
		while(next != null);

		return lst;
	}

	private void buildUpdateSet()
	{
		to_delete = new TreeSet<String>();
		to_upload = new TreeSet<String>();

		for(String key : s3objs.keySet())
		{
			if (local_files.containsKey(key))
			{
				S3ObjectSummary o = s3objs.get(key);
				File f = local_files.get(key);
				if (f.length() != o.getSize())
				{
					to_upload.add(key);
				}
			}
			else
			{
				to_delete.add(key);
			}
		}

		for(String key : local_files.keySet())
		{
			if (!s3objs.containsKey(key))
			{
				to_upload.add(key);
			}
		}

		System.out.println("Delete list: " + to_delete.size());
		System.out.println("To upload: " + to_upload.size());

	}

	private void doDelete(AmazonS3Client svc)
		throws Exception
	{
		for(String key : to_delete)
		{
			svc.deleteObject(BUCKET, key);
			System.out.println("Deleted: " + key);
		}

	}

	private void doUpload(AmazonS3Client svc)
		throws Exception
	{
		for(String key : to_upload)
		{
			System.out.println("Uploading: " + key);
			File f = local_files.get(key);

			PutObjectRequest put = new PutObjectRequest(BUCKET, key, f);
			put.setCannedAcl(CannedAccessControlList.PublicRead );

			ObjectMetadata om = new ObjectMetadata();
			om.setContentType("image/png");
			put.setMetadata(om);

			svc.putObject(put);
			System.out.println("Added: " + key);

		}

	}

	private void populateFileTree(File f, String pre, TreeMap<String, File> file_map)
	{
		if (f.isFile())
		{
			String name = pre + f.getName();

			if (name.endsWith(".png"))
			{
				file_map.put(name, f);
			}
			return;
		}
		if (f.isDirectory())
		{
			String name = pre + f.getName() + "/";
			if (name.equals("images/")) name ="";
			for(File sub : f.listFiles())
			{
				populateFileTree(sub, name, file_map);
			}
			return;
		}
		

	}




}
