package util;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.google.common.collect.Lists;
import common.service.impl.OpenApiServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class AwsS3Util
{
    private static final Logger logger = LoggerFactory.getLogger(AwsS3Util.class);

    private static AwsS3Util awsS3Util = new AwsS3Util();

    private AmazonS3 s3;

    private AwsS3Util() {
        String accessKey = "AKIAPSKINGJFIZHEFNWQ";
        String secretKey = "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";

        if ((accessKey != null) && (secretKey != null)) {
            AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);

            ClientConfiguration config = new ClientConfiguration();
            String proxyHost = System.getProperty("http.proxyHost");
            String proxyPort = System.getProperty("http.proxyPort");
            if (proxyHost != null && proxyPort != null) {
                config.setProxyHost(proxyHost);
                config.setProxyPort(Integer.valueOf(proxyPort));
            }

            if (s3 == null)
                s3 = new AmazonS3Client(credentials, config);

            s3.setRegion(com.amazonaws.regions.Region.getRegion(Regions.CN_NORTH_1));
        }
    }

    public static AwsS3Util getInstance() {
        return awsS3Util;
    }

    public AmazonS3 getAmazonS3() {
        return s3;
    }

    public List<String> getS3Keys(String bucket, String prefix) {
        List<String> rtnList = Lists.newArrayList();
        ObjectListing objectListing = s3.listObjects(new ListObjectsRequest()
                .withBucketName(bucket)
                .withPrefix(prefix));
        for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
            rtnList.add(objectSummary.getKey());
        }
        return rtnList;
    }

    public long uploadStreamToS3(String bucket, String s3key, InputStream in, String contentType, long contentLength)
            throws IOException {
        ObjectMetadata md = new ObjectMetadata();
        if (contentType != null)
            md.setContentType(contentType);
        md.setContentLength(contentLength);
        AwsS3Util.getInstance().getAmazonS3().putObject(bucket, s3key, in, md);
        return contentLength;
    }

    public long uploadStringToS3(String s3bucket, String s3key, String str)
            throws IOException {
        final byte[] bytes = str.getBytes("UTF-8");
        BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(bytes));
        try {
            return uploadStreamToS3(s3bucket, s3key, bis, "text/plain; charset=UTF-8", bytes.length);
        } finally {
            IOUtil.close(bis);
        }
    }

    public String downloadStringFromS3(String bucket, String s3key) throws IOException {
        return new String(downloadBytesFromS3(bucket, s3key), "UTF-8");
    }

    public byte[] downloadBytesFromS3(String bucket, String s3key) throws IOException {
        InputStream is = null;
        ByteArrayOutputStream bos = null;
        try {
            is = downloadStreamFromS3(bucket, s3key);
            bos = new ByteArrayOutputStream();
            IOUtil.copy(is, bos);
            return bos.toByteArray();
        } finally {
            if (bos != null)
                IOUtil.close(bos);
            if (is != null)
                IOUtil.close(is);
        }
    }

    public InputStream downloadStreamFromS3(String bucket, String s3key) {
        return getS3Object(bucket, s3key).getObjectContent();
    }

    public void deleteS3Object(String bucket, String s3key) {
        AwsS3Util.getInstance().getAmazonS3().deleteObject(bucket, s3key);
    }

    private S3Object getS3Object(String bucket, String s3key) {
        return AwsS3Util.getInstance().getAmazonS3().getObject(bucket, s3key);
    }

    public static void main(String[] args) {
        OpenApiServiceImpl openApiService = new OpenApiServiceImpl();
        openApiService.listInfo4AppData("2017-12-21");
    }
}