package de.dml.application.musicFileManagement.util;

import java.io.File;
import java.io.Serializable;
import java.util.List;

import com.mpatric.mp3agic.Mp3File;

import de.dml.application.persistence.core.entity.CoreMusicTypeVersion;
import de.dml.application.persistence.core.entityDao.CoreMusicTypeVersionDao;
import de.dml.application.util.ContextLookupUtil;
import de.dml.application.util.StringUtil;

/**
 * Provides utility functions for easy music file management
 * 
 * @author ssmits
 */
public class MusicFileManagementUtil implements Serializable {
	private static final long serialVersionUID = 1L;

	public static final String[] explicitContentIndicatorKeys = new String[] {
		"(dirty)", "(Dirty)", "(DIRTY)",
		"(explicit)", "(Explicit)", "(EXPLICIT)"
	};
	
	private MusicFileManagementUtil() {
		// Prevents Object instantiation
	}
	
	/**
	 * Returns whether the file-name contains indicators for explicit content.
	 * 
	 * @param file The file to analyse
	 * @return Whether an indicator for explicit content has been found within the filename
	 * @throws Exception
	 */
	public static Boolean mp3fileContainsExplicitContentIndicator(final File file) throws Exception {
		final String fileName = file.getName();
		
		if (fileName.equalsIgnoreCase("(dirty)") || fileName.equalsIgnoreCase("[dirty]") || fileName.equalsIgnoreCase("(explicit)") || fileName.equalsIgnoreCase("[explicit]")) {
			return true;
		} else {
			// Check ID3 tag information
			Mp3File mp3 = new Mp3File(file.getAbsolutePath());
			
			if (mp3.hasId3v2Tag()) {
				if (StringUtil.containsKeyword(mp3.getId3v2Tag().getTitle(), explicitContentIndicatorKeys)) {
					return true;
				}
			} else if (mp3.hasId3v1Tag()) {
				if (StringUtil.containsKeyword(mp3.getId3v1Tag().getTitle(), explicitContentIndicatorKeys)) {
					return true;
				}
			} else {
				throw new IllegalStateException("Given mp3 file has no readable ID3 tag information");
			}
		}
		
		return false;
	}
	
	/**
	 * Estimates the music type version by the title ID3 Tag against the CoreMusicTypeVersionNamingVariation catalog
	 * 
	 * @param file The file to analyse
	 * @return CoreMusicTyperVersion JPA Entity instance
	 * @throws Exception If something went wrong
	 */
	public static CoreMusicTypeVersion getEstimatedMusicTypeVersion(final File file) throws Exception {
		CoreMusicTypeVersionDao coreMusicTypeVersionDao = ContextLookupUtil.getBean(CoreMusicTypeVersionDao.class);
		
		// Check ID3 tag information
		Mp3File mp3 = new Mp3File(file.getAbsolutePath());
		String title = "";
		
		if (mp3.hasId3v2Tag()) {
			title = mp3.getId3v2Tag().getTitle();
		} else if (mp3.hasId3v1Tag()) {
			title = mp3.getId3v2Tag().getTitle();
		} else {
			throw new IllegalStateException("Given mp3 file has no readable ID3 tag information");
		}
		
		for (CoreMusicTypeVersion typeVersion : coreMusicTypeVersionDao.findByRecordStatus(true)) {
			List<String> alternativeNames = typeVersion.getAlternativeNames();
			String[] alternativeNamesArray = new String[alternativeNames.size()];
			int alternativeNamesCounter = 0;
			
			for (String alternativeName : alternativeNames) {
				alternativeNamesArray[alternativeNamesCounter] = alternativeName;
				alternativeNamesCounter++;
			}
			
			if (StringUtil.containsKeyword(title, alternativeNamesArray)) {
				return typeVersion;
			}
		}
		
		// Return with unknown value
		return coreMusicTypeVersionDao.findOneById(1);
	}
}
