package routines;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;

/*
 * user specification: the function's comment should contain keys as follows: 1. write about the function's comment.but
 * it must be before the "{talendTypes}" key.
 * 
 * 2. {talendTypes} 's value must be talend Type, it is required . its value should be one of: String, char | Character,
 * long | Long, int | Integer, boolean | Boolean, byte | Byte, Date, double | Double, float | Float, Object, short |
 * Short
 * 
 * 3. {Category} define a category for the Function. it is required. its value is user-defined .
 * 
 * 4. {param} 's format is: {param} <type>[(<default value or closed list values>)] <name>[ : <comment>]
 * 
 * <type> 's value should be one of: string, int, list, double, object, boolean, long, char, date. <name>'s value is the
 * Function's parameter name. the {param} is optional. so if you the Function without the parameters. the {param} don't
 * added. you can have many parameters for the Function.
 * 
 * 5. {example} gives a example for the Function. it is optional.
 */
public class constant {
	
	/* Directory structure pre project root. Localtion of config_root directory that defined all environments prd, tst1, dev1,... */ 
	public static final String hardCodedRootDirectory ="/cimt";
	
	/* Framework specific returncode collections*/ 
	private static HashSet<Integer> rerunErrorCodes = null; 
	
	public static final String unusableDataErrorCodeListSQL="1,2,3,7,9";
	public static final String rerunErrorCodeListSQL="1,2,3,7,9,20,22,23,25,29";
	public static final String onlyUsableDataReturncodeConstraintSQL="( Return_Code not in ("+unusableDataErrorCodeListSQL+") and Return_Code <100)";
	public static final String onlyCompletedRunsConstraintSQL="( Return_Code not in ("+rerunErrorCodeListSQL+") and Return_Code <100)";
	
	/* Database Connection names*/
	public static final String pg_manage_connectionName="pgManageConnection";
	
	/* Date Patterns */
	public static final String timestampPatternForSQL="yyyy-MM-dd HH:mm:ss";
	public static final String timestampPatternForSQLHD="yyyy-MM-dd HH:mm:ss.SSS";
	public static final String timestampPatternCompactSortable="yyyyMMddHHmmss";
	public static final String timestampPatternCompactSortableHD="yyyyMMddHHmmssSSS";
	
	
	/* Content group default */ 
	public static final String contentGroup_allData="*ALL*";
	
	/* caches for calculated values */
    private static Date farFutureDate;
    private static String farFutureDateAsDBConst;
	private static Date farPastDate;
	
	/* Implicit context load helper */
	private static String ImplicitContextFilePath;

	private static LcagLogger log = LcagLogger.getLogger(constant.class);	
	
	/**
	 * getFarFutureDate: 
	 * @param none
	 * @return Date constant, defined as far future date
	 * 
	 * {talendTypes} Date
	 * 
	 * {Category} constant (check)
	 * 
	 * {example} getFarFutureDate
	 */
   public static Date getFarFutureDate() {
    	if (farFutureDate == null) {
    		Calendar cal = Calendar.getInstance();
    		cal.setTimeInMillis(0); /* Reset time part*/
    		cal.set(2099, 11, 31); /* 11= December */
    		farFutureDate = cal.getTime();
    		cal = null;
    	}
    	return farFutureDate;
    }
	
	public static String getFarFutureDateAsDBConst() {
		if(farFutureDateAsDBConst==null) {
			farFutureDateAsDBConst=TalendDate.formatDate(timestampPatternForSQL, getFarFutureDate());
		}
    	return farFutureDateAsDBConst;
    }
    /**
	 * getFarPastDate: 
	 * @param none
	 * @return Date constant, defined as far past date
	 * 
	 * {talendTypes} Date
	 * 
	 * {Category} constant (check)
	 * 
	 * {example} getFarPastDate
	 */
    public static Date getFarPastDate() {
    	if (farPastDate == null) {
    		Calendar cal = Calendar.getInstance();
    		cal.setTimeInMillis(0);
    		farPastDate = cal.getTime();
    		cal = null;
    	}
    	return farPastDate;
    }
    
   public static String getImplicitContextFilePath(String actualImplicitContextFilePath, String projectName,String contextName) {
	   // This routine is run at each job start if Implicit context load is set in Job->Extra
	    log.trace("getImplicitContextFilePath(%s, %s, %s) called", actualImplicitContextFilePath, projectName, contextName);
	    
	    String[] ctxNameParts = contextName.split("_");

	    if ( ctxNameParts.length > 1 ) {
	    	LcagLogger.getLogger(log).warn("getImplicitContextFilePath: Context values passed by TAC. Temp context name %s set to %s",
	    			contextName, ctxNameParts[0]
	    	);

	    	// Reset context name to know values to prevent file not found exception
	    	contextName = ctxNameParts[0];
	    }
	    
	    if(ImplicitContextFilePath==null) {
    		ImplicitContextFilePath= String.format("%s/%s/config_root/amc_db_%s.properties",
    				hardCodedRootDirectory, StringHandling.DOWNCASE(projectName), contextName
    		);
    	    log.trace("getImplicitContextFilePath: ImplicitContextFilePath initialized");
    	} 
	    log.debug("getImplicitContextFilePath: returning ImplicitContextFilePath %s", ImplicitContextFilePath);
    	return ImplicitContextFilePath;
    }
   
   

    
    /**
	 * isReturnCodeTheRerunError: returns date + given months
	 * @param returnCode job return code
	 * @return if return code is an rerun error
	 * 
	 * {talendTypes} Integer
	 * 
	 * {Category} constant (check)
	 * 
	 * {example} isReturnCodeTheRerunError(0).
	 * 
	 * This function is placed here due to reference tracking 
	 * issues in talend. It uses the "rerunErrorCodeListSQL" 
	 * constant. Would function be placed in other module and 
	 * used in Job, it could lead to "rerunErrorCodeListSQL" not 
	 * beeing included in exported job.
	 * 
	 */
    public static boolean isReturnCodeTheRerunError(Integer returnCode) {
    	// lazy initialization, happens only once
    	if (rerunErrorCodes == null) {
    		rerunErrorCodes = new HashSet<Integer>();
    		String[] unusableDataErrorCodeArray = rerunErrorCodeListSQL.split(",");
    		for (String string : unusableDataErrorCodeArray) {
    			rerunErrorCodes.add(Integer.parseInt(string));
			}
    	}
    	
    	// check if return code is a rerun error
    	return rerunErrorCodes.contains(returnCode);
    }
}
