import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.ho.yaml.Yaml;

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.transfer.Download;
import com.amazonaws.services.s3.transfer.TransferManager;

public class LoadTableFromS3 {

	public static String key     = "";
	public static String table     = "";
	public static String bucket     = "";
	public static String configFilePath = "/mnt/data/ETL/java/accounting/config/config.yml";
	
	public static void main(String[] args) throws Exception{
		Map<String,Object> conf = new HashMap<String,Object>();
		
		Options options = new Options();
		//Optional Params
		options.addOption("configFilePath",true,"(Optional) Config.yml file for this cli tool (Default: /mnt/data/ETL/java/accounting/config/config.yml)");
		
		//Required Params
		options.addOption("key",true,"Path to the data files on S3");
		options.addOption("bucket",true,"Bucket at which SQL files are stored");
		options.addOption("table",true,"Table to be loaded up");
		
		if(args.length==0){
			HelpFormatter formatter = new HelpFormatter();
			formatter.printHelp("ant run -Dargs='paramA=xxx paramB=yyy .....'", options);
			System.exit(1);
		}
		//Parsing arguments
		CommandLineParser parser = new GnuParser();
		CommandLine cmd = parser.parse( options, args);
		if(cmd.hasOption("configFilePath")){
			configFilePath = cmd.getOptionValue("configFilePath");
		}
		if(!cmd.hasOption("key") || !cmd.hasOption("table") || !cmd.hasOption("bucket")){
			System.out.println("Missing parameters. Please provide key, table and bucket. (eg. ant run -Dargs='-key=xxx -bucket=yyy -table=zzzz')");
			System.exit(1);
		}
		conf = (Map)Yaml.load(new File(configFilePath));
	    
	    //Now, query database with sql
		Connection conn = null;
        Statement stmt = null;
        try{
           Class.forName("org.postgresql.Driver");
           Properties props = new Properties();
           props.setProperty("user", (String)conf.get("redshiftUsername"));
           props.setProperty("password", (String)conf.get("redshiftPassword"));
           conn = DriverManager.getConnection((String)conf.get("redshiftHost"), props);
        
           System.out.println("Connected to: "+(String)conf.get("redshiftHost"));
           stmt = conn.createStatement();
           
           String sql = "copy "+cmd.getOptionValue("table")+" from 's3://"+cmd.getOptionValue("bucket")+"/"+cmd.getOptionValue("key")
        		   +"' CREDENTIALS 'aws_access_key_id="+(String)conf.get("accessKey")+";aws_secret_access_key="+(String)conf.get("accessSecret")
        		   +"' delimiter '\t' NULL AS 'null' ESCAPE gzip;";
           System.out.println("Running: "+sql);
           stmt.execute(sql);
           
           stmt.close();
           conn.close();
           System.exit(1);
        }catch(Exception ex){
           //For convenience, handle all errors here.
           ex.printStackTrace();
        }finally{
           //Finally block to close resources.
           try{
              if(stmt!=null)
                 stmt.close();
           }catch(Exception ex){
           }// nothing we can do
           try{
              if(conn!=null)
                 conn.close();
           }catch(Exception ex){
              ex.printStackTrace();
           }
        }
        System.out.println("Finished connectivity test.");
     }
	}


