package com.theorchard.javaowsassetbulkscript.logic;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;

import com.theorchard.javaowsassetbulkscript.api.TrackItem;

public class AssetDownloader {

    private String path;

    AWSWrapper wrapper;

    public AssetDownloader(AWSDetails awsDetails) {
        path = awsDetails.getPath();

        wrapper = new AWSWrapper(awsDetails.getPublicKey(), awsDetails.getPrivateKey(), awsDetails.getBucket(), awsDetails.getRegion());

        wrapper.connect();
    }

    public File downloadMetadataSpreadsheet(String ftId) throws IOException, InvalidFormatException {

        List<String> files = wrapper.listFiles(path, ftId + "_");

        files.forEach(file -> System.out.println(file));

        String labelFolderName = "";
        if (files.size() > 0) {
            String fileName = files.get(0);

            fileName = fileName.replaceAll(path+"/", "");

            labelFolderName = fileName.substring(0, fileName.indexOf("/"));
        }

        File labelExcel = new File("Downloads/"+ path +"/" + labelFolderName + "/" + labelFolderName+".xls");

        if(!labelExcel.exists()) {
            wrapper.download(path+"/"+labelFolderName, labelFolderName + ".xls", labelExcel);
        }

        return labelExcel;
    }

    public File download(String file) throws Exception {
        File target = new File(("Downloads/"+path+"/"+file).replaceAll("//", "/"));
        if(!target.exists()) {
            if (!exists(file)) {
                throw new Exception("File does not exist in the Bucket: "+path+"/"+file);
            }

			try {
				wrapper.download(path, file, target);
			} catch (Exception e) {
				e.printStackTrace();
				String msg = "Download of file " + target.getName() + " failed: " + e.getMessage();
            	throw new Exception(msg);
            }
            
        }
        return target;
    }

    public File downloadProductTrack(DeliveredProduct product, TrackItem item) throws Exception {
        List<DeliveredTrack> tracks = product.getTracks();

        for (DeliveredTrack track : tracks) {
            String asset = track.getAsset();
            if (asset.endsWith(".mp3") || asset.endsWith(".mov") || asset.endsWith(".mp4")) {
                throw new Exception("Unexpected asset type: "+asset+ " ("+product.getProductCode()+")");
            }
            if (track.getIsrc().equals(item.getIsrc())) {
                return download(track.getAsset());
            }
        }

        return null;
    }

    public void close() {
        try {
            wrapper.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean exists(String fileName) {
        return wrapper.fileExists(path, fileName);
    }

    public void removeAllDownloadsForLabel(String labelId) {
        removeAllDownloadsForLabel(labelId, path);
    }

    public static void removeAllDownloadsForLabel(String labelId, String path) {
        File downloadDir = new File(("Downloads/"+path).replaceAll("//", "/"));

        Collection<File> files = FileUtils.listFilesAndDirs(downloadDir, DirectoryFileFilter.DIRECTORY, new WildcardFileFilter(labelId+"*"));

        for (File file : files) {
            try {
                if (file.isDirectory() && !file.equals(downloadDir)) {
                    FileUtils.cleanDirectory(file);
                    FileUtils.deleteDirectory(file);
                } else if (!file.equals(downloadDir)) {
                    FileUtils.deleteQuietly(file);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    public void removeAlbumDownloadFolderForLabel(String labelId, String albumId) {
    	removeAlbumDownloadFolderForLabel(labelId, albumId, path);
    }

	private static void removeAlbumDownloadFolderForLabel(String labelId, String albumId, String path) {
		File downloadDir = new File(("Downloads/" + path).replaceAll("//", "/"));

		// find the folder of the label
		Collection<File> files = FileUtils.listFilesAndDirs(downloadDir, DirectoryFileFilter.DIRECTORY,
				new WildcardFileFilter(labelId + "*"));

		// For some reason, the og folder ends up in this list
		files.remove(downloadDir);
		
		for (File file : files) {
			if (file.isDirectory() && !file.equals(downloadDir)) {
				Collection<File> albumDirs = FileUtils.listFilesAndDirs(file, DirectoryFileFilter.DIRECTORY,
						new WildcardFileFilter(albumId));
				// find the folder of the album, remove top folder
				albumDirs.remove(file);
				// albumDirs should only contain one entry now
				for (File albumDir : albumDirs) {
					if (albumDir.isDirectory() && albumDir.getName().equals(albumId)) {
						System.out.println("Deleting folder " + albumDir.getAbsolutePath());
						try {
							FileUtils.cleanDirectory(albumDir);
							FileUtils.deleteDirectory(albumDir);
							break;
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
				
			}
		}
	}
}
