package generateCalendar;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;

import dataWarehousingTools.DashboardFile;


public class GenerateCalendar 
{

//  PostgreSQL table to receive this data
//	
//  create table calendar 
//  (
//     id                                serial      not null,    -- populated automatically by PostgreSQL
//     calendar_date                     date,
//     day_of_week                       varchar(9),
//     day_of_month                      integer,
//     day_of_year                       integer,
//     month_number                      integer,
//     week_number                       integer,
//     month_name                        varchar(9),
//     year                              integer,
//     public_holiday_england_and_wales  boolean,                 -- populated manually, not by this process
//     public_holiday_scotland           boolean,                 -- populated manually, not by this process
//     public_holiday_northern_ireland   boolean,                 -- populated manually, not by this process
//     quarter_number                    integer,
//	   quarter_name                      varchar(6),
//     weekend                           boolean,
//     first_date_of_month               date,
//     last_date_of_month                date,
//     constraint primary_key_calendar   primary key (id)
//  );

	public static void main(String[] args) 
	{
		String fileName;
		DashboardFile dataFile;
		Calendar date;
		Calendar firstDateOfMonth;
		Calendar lastDateOfMonth;
		Calendar endDate;
		SimpleDateFormat dateFormat;
		Locale locale;
		int fromYear = 0;
		int fromMonth = 0;
		int fromDay = 0;
		int toYear = 0;
		int toMonth = 0;
		int toDay = 0;
		int yearNumber;
		int monthNumber;
		int quarterNumber;
		int dayOfWeek;
		String quarterString;
		String weekend;
		String fromDate;
		String toDate;

		if (args.length != 3)
			usage();

		fileName = new String(args[0]);
		fromDate = new String(args[1]);
		toDate = new String(args[2]);

		try
		{
			fromYear = Integer.parseInt(fromDate.substring(0, 4));
			fromMonth = Integer.parseInt(fromDate.substring(5, 7));
			fromDay = Integer.parseInt(fromDate.substring(8, 10));
			toYear = Integer.parseInt(toDate.substring(0, 4));
			toMonth = Integer.parseInt(toDate.substring(5, 7));
			toDay = Integer.parseInt(toDate.substring(8, 10));
		}
		catch (NumberFormatException e)
		{
			usage();
		}

		if ((fromMonth < 1) || (fromMonth > 12))
			usage();
		if ((toMonth < 1) || (toMonth > 12))
			usage();
		if ((fromDay < 1) || (fromDay > 31))
			usage();
		if ((toDay < 1) || (toDay > 31))
			usage();

		locale = new Locale("ENGLISH", "UK");
		
		date = Calendar.getInstance();
        date.set(fromYear, fromMonth - 1, fromDay);		    // Month number starts from zero; January = 0, February = 1, etc.
        
        endDate = Calendar.getInstance();
        endDate.set(toYear, toMonth - 1, toDay);		    // Month number starts from zero; January = 0, February = 1, etc.
		
    	dateFormat = new SimpleDateFormat("yyyy-MM-dd");	// This date format is unambiguous for input to PostgreSQL, Netezza and some other databases

		firstDateOfMonth = Calendar.getInstance();
		lastDateOfMonth = Calendar.getInstance();
        
        dataFile = new DashboardFile(fileName);
 
    	dataFile.PutLine
    	(
			"calendar_date," +
			"day_of_week," +
			"day_of_month," +
			"day_of_year," +
			"month_number," +
			"week_number," +
			"month_name," +
			"year," + 
			"quarter_number," +
			"quarter_name," +
			"weekend," +
			"first_date_of_month," +
			"last_date_of_month"
    	);
    	
        
        while (date.before(endDate))
        {
        	yearNumber = date.get(Calendar.YEAR);
        	
        	monthNumber = date.get(Calendar.MONTH) + 1;
        	if (monthNumber < 4)
        		quarterNumber = 1;
        	else if (monthNumber < 7)
        		quarterNumber = 2;
        	else if (monthNumber < 10)
        		quarterNumber = 3;
        	else
        		quarterNumber = 4;
        	
        	quarterString = new String(yearNumber + "Q" + quarterNumber);
        	
        	dayOfWeek = date.get(Calendar.DAY_OF_WEEK);
        	if ((dayOfWeek == Calendar.SATURDAY) || (dayOfWeek == Calendar.SUNDAY))
        		weekend = new String("TRUE");
        	else
        		weekend = new String("FALSE");
        	
        	firstDateOfMonth = (Calendar)date.clone();
        	firstDateOfMonth.set(Calendar.DATE, date.getActualMinimum(Calendar.DAY_OF_MONTH));
        	
        	lastDateOfMonth = (Calendar)date.clone();
        	lastDateOfMonth.set(Calendar.DATE, date.getActualMaximum(Calendar.DAY_OF_MONTH));
       		
        	dataFile.PutLine
        	(
        		dateFormat.format(date.getTime()) + "," +
        		date.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, locale) + "," +
        		date.get(Calendar.DAY_OF_MONTH) + "," +
        		date.get(Calendar.DAY_OF_YEAR) + "," +
        		monthNumber + "," +
        		date.get(Calendar.WEEK_OF_YEAR) + "," +
        		date.getDisplayName(Calendar.MONTH, Calendar.LONG, locale) + "," +
        		yearNumber + "," +
        		quarterNumber + "," +
        		quarterString  + "," +
        		weekend  + "," +
        		dateFormat.format(firstDateOfMonth.getTime()) + "," +
        		dateFormat.format(lastDateOfMonth.getTime())
        	);
        	date.add(Calendar.DATE, 1);
        }
        dataFile.Close();
	}
	
	private static void usage()
	{
		System.out.println("");
		System.out.println("Usage: GenerateCalendar file from_date to_date");
		System.out.println("");
		System.out.println("    file:       name (or path) of csv file of the dates to load the calendar dimension");
		System.out.println("    from_date:  earliest date in the calendar dimension.  Must be in format yyyy-mm-dd");
		System.out.println("    to_date:    latest date in the calendar dimension.  Must be in format yyyy-mm-dd"); 
		System.out.println("");
		System.out.println("Documentation: http://www.thedatastudio.net/data_profiler_documentation.htm");
		System.exit(1);
	}
}

