package models;

import com.amazonaws.services.s3.model.*;
import com.google.gson.annotations.Expose;
import config.GlobalConfig;
import org.hibernate.annotations.Type;
import org.joda.time.DateTime;
import play.db.jpa.Model;
import play.libs.WS;
import play.mvc.Router;
import util.S3Provider;

import javax.persistence.Entity;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static config.GlobalConfig.CLOUDFRONT_URL;
import static config.GlobalConfig.THUMB_URL;

/**
 * Holder class for files stored in S3
 */
@Entity
public class DBFile extends Model implements Event {

    public URL fileUrl;
    @Searchable
    public String filename;
    @Expose
    @Searchable
    public String title;


    @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
    public DateTime uploadDate = DateTime.now();

    public DBFile() {
    }

    public DBFile(File file) throws MalformedURLException {
        this.filename = UUID.randomUUID().toString();
        String bucketName = S3Provider.PUBLICBUCKET;
        S3Provider.getS3().putObject(new PutObjectRequest(bucketName, filename, file).withCannedAcl(CannedAccessControlList.PublicRead));
        fileUrl = new URL("https://s3-eu-west-1.amazonaws.com/" + bucketName + "/" + filename);
    }

    public DBFile(File file, String originalFilename) throws MalformedURLException {
        String bucketName = S3Provider.PUBLICBUCKET;
        this.filename = originalFilename;
        S3Provider.getS3().putObject(new PutObjectRequest(bucketName, filename, file).withCannedAcl(CannedAccessControlList.PublicRead));
        fileUrl = new URL("https://s3-eu-west-1.amazonaws.com/" + bucketName + "/" + originalFilename);
    }
    public DBFile(File file, String originalFilename, String title) throws MalformedURLException {
        String bucketName = S3Provider.PUBLICBUCKET;
        this.filename = originalFilename;
        this.title=title;
        S3Provider.getS3().putObject(new PutObjectRequest(bucketName, filename, file).withCannedAcl(CannedAccessControlList.PublicRead));
        fileUrl = new URL("https://s3-eu-west-1.amazonaws.com/" + bucketName + "/" + originalFilename);
    }

    public DBFile(String targetURL) {
        String bucketName = S3Provider.DEFAULTBUCKET;
        createFile(targetURL, bucketName, false);
    }

    public static DBFile createPublic(String targetURL) {
        DBFile cFile = new DBFile();
        cFile.createFile(targetURL, S3Provider.PUBLICBUCKET, true);
        return cFile;
    }

    public static DBFile createPrivate(String targetURL) {
        DBFile cFile = new DBFile();
        cFile.createFile(targetURL, S3Provider.DEFAULTBUCKET, false);
        return cFile;
    }

    public S3ObjectInputStream file() throws FileNotFoundException {
        S3Object object = S3Provider.getS3().getObject(new GetObjectRequest(S3Provider.DEFAULTBUCKET, filename));
        return object.getObjectContent();
    }

    private void createFile(String targetURL, String bucketName, boolean isPublic) {
        this.filename = UUID.randomUUID().toString();
        InputStream photostream = WS.url(targetURL).get().getStream();
        ObjectMetadata metadata = new ObjectMetadata();
        bucketName = S3Provider.PUBLICBUCKET;
        S3Provider.getS3().putObject(new PutObjectRequest(bucketName, filename, photostream, metadata).withCannedAcl(CannedAccessControlList.PublicRead));
//        if (isPublic) {
//            S3Provider.getS3().putObject(new PutObjectRequest(bucketName, filename, photostream, metadata).withCannedAcl(CannedAccessControlList.PublicRead));
//        }else{
//            S3Provider.getS3().putObject(new PutObjectRequest(bucketName, filename, photostream, metadata).withCannedAcl(CannedAccessControlList.AuthenticatedRead));
//        }
        try {
            fileUrl = new URL("https://s3-eu-west-1.amazonaws.com/" + bucketName + "/" + filename);
        } catch (MalformedURLException e) {
            throw new RuntimeException("Malformed url");
        }
    }

    public String thumb(int height, int width) {

        if (!GlobalConfig.getInstance().isThumbotFrontUp()) {
            return fileUrl.toString();
        } else if (!GlobalConfig.getInstance().isCloudFrontUp()) {
            return THUMB_URL + "" + height + "x" + width + "/" + fileUrl;
        }
        return CLOUDFRONT_URL + "unsafe/" + height + "x" + width + "/" + fileUrl;

    }

    public void permDelete() {
        String bucketName = S3Provider.PUBLICBUCKET;
        S3Provider.getS3().deleteObject(new DeleteObjectRequest(bucketName, filename));
    }

    @Override
    public DateTime getStartDate() {
        return null;
    }

    @Override
    public String getTitle() {
        return this.title;
    }

    @Override
    public String getCalendarContent() {
        return null;
    }

    @Override
    public String getUrl() {
        return this.fileUrl.toString();
    }

    @Override
    public String getUploadedBy() {
        return null;
    }

    @Override
    public JSONEvent getEvent() {
        return null;
    }

    public String toString(){
        return getTitle();
    }
}
