syntax = "proto3";

package jd3;

option java_package = "jdplus.toolkit.base.protobuf.toolkit";
option java_outer_classname = "ToolkitProtos";

enum SelectionType {
	SPAN_ALL=0;
	SPAN_FROM=1;
	SPAN_TO=2;
	SPAN_BETWEEN=3;
	SPAN_LAST=4;
	SPAN_FIRST=5;
	SPAN_EXCLUDING=6;
    SPAN_NONE=7;
}

message Date {
  // Year of the date. Must be from 1 to 9999, or 0 to specify a date without
  // a year.
  int32 year = 1;

  // Month of a year. Must be from 1 to 12, or 0 to specify a year without a
  // month and day.
  int32 month = 2;

  // Day of a month. Must be from 1 to 31 and valid for the year and month, or 0
  // to specify a year by itself or a year and month where the day isn't
  // significant.
  int32 day = 3;
}


message TimeSelector{
	SelectionType type = 1;
	int32 n0 = 2;
	int32 n1 = 3;
	Date d0 = 4;
	Date d1 = 5;
}

enum ParameterType{
	// Similar to null
	PARAMETER_UNUSED = 0;
	// Parameter is used but not defined (to be estimated)
	PARAMETER_UNDEFINED = 1;
	PARAMETER_FIXED = 2;
	PARAMETER_INITIAL = 3;
	PARAMETER_ESTIMATED = 4;
}

message Parameter{
	double value = 1;
	ParameterType type = 2;
	string description = 3;
}

message ParametersEstimation{
	repeated double value = 1;
	repeated double score = 2;
	Matrix covariance = 3;
	string description = 4;
}

message TsPeriod{
	int32 annual_frequency = 1;
	int32 year = 2;
	int32 pos = 3;
}

message TsData{
	string name = 1;
	int32 annual_frequency = 2;
	int32 start_year = 3;
	int32 start_period = 4;
	repeated double values = 5;
}

message Doubles{
	string name = 1;
	repeated double values = 2;
}

message Matrix{
	string name = 1;
	int32 nrows = 2;
	int32 ncols = 3;
	repeated double values = 4;
}

message TsMatrix{
	string name = 1;
	int32 annual_frequency = 2;
	int32 start_year = 3;
	int32 start_period = 4;
	Matrix values = 5;
}

message StatisticalTest{
	double value = 1;
	double pvalue = 2;
	string description = 3;
}

message OneWayAnova{
	// sum_f(n_f(X_f-X)^2) = ss explained by the factors
	double SSM = 1;
	// nfactors-1
	int32 dfm = 2;
	// sum_f(sum_i(x_if-X_f)^2) = residual ss
	double SSR = 3;
	// N-nfactors
	int32 dfr = 4;

	StatisticalTest test = 5;
}


message ParameterEstimation{
	string name = 1;
	double value = 2;
	double stde = 3;
	double pvalue = 4;
}

message LikelihoodStatistics{
	int32 nobs = 1;
	int32 neffectiveobs = 2;
	int32 nparams = 3;
	int32 degrees_of_freedom = 4;
	double log_likelihood = 5;
	double adjusted_log_likelihood = 6;
	double aic = 7;
	double aicc = 8;
	double bic = 9;
	double bicc = 10;
	double bic2 = 11;
	double hannan_quinn = 12;
	double ssq = 13;
}

message DiffuseLikelihoodStatistics{
	int32 nobs = 1;
	int32 ndiffuse = 2;
	int32 nparams = 3;
	int32 degrees_of_freedom = 4;
	double log_likelihood = 5;
	double adjusted_log_likelihood = 6;
	double aic = 7;
	double aicc = 8;
	double bic = 9;
	double ssq = 13;
	double ssqerr = 14;
	double ldet = 15;
	double dcorrection = 16;
}



message NIIDTests{
	/* Normality */
	StatisticalTest mean = 1;
	StatisticalTest skewness = 2;
	StatisticalTest kurtosis = 3;
	StatisticalTest doornik_hansen = 4;

	/* Independence */
	StatisticalTest ljung_box = 5;
	StatisticalTest box_pierce = 6;
	StatisticalTest seasonal_ljung_box = 7;
	StatisticalTest seasonal_box_pierce = 8;

	/* Randomness */
    StatisticalTest runs_number = 9;
	StatisticalTest runs_length = 10;
	StatisticalTest up_down_runs_number = 11;
	StatisticalTest up_down_runs_length = 12;

	/* Linearity */
	StatisticalTest ljung_box_on_squares = 13;
	StatisticalTest box_pierce_on_squares = 14;
}

/* Calendars */

message ValidityPeriod {
	Date start = 1;
	Date end = 2;
}

enum CalendarEvent{
	HOLIDAY_UNSPECIFIED = 0;
    /**
     * January, 1
     */
    HOLIDAY_NEWYEAR = 1;
    /**
     * Shrove Monday (48 days before Easter)
     */
    HOLIDAY_SHROVEMONDAY = 2;
    /**
     * Shrove Tuesday (47 days before Easter)
     */
    HOLIDAY_SHROVETUESDAY = 3;
    /**
     * AshWednesday (46 days before Easter)
     */
    HOLIDAY_ASHWEDNESDAY = 4;
    /**
     * Easter
     */
    HOLIDAY_EASTER = 5;
    /**
     * Julian Easter.
     */
    HOLIDAY_JULIANEASTER = 6;
    /**
     * Last Thursday before Easter
     */
    HOLIDAY_MAUNDYTHURSDAY = 7;
    /**
     * Last Friday before Easter
     */
    HOLIDAY_GOODFRIDAY = 8;
    /**
     * First Monday after Easter
     */
    HOLIDAY_EASTERMONDAY = 9;
    /**
     * Ascension (40 days after Easter)
     */
    HOLIDAY_ASCENSION = 10;
    /**
     * Pentecost (50 days after Easter)
     */
    HOLIDAY_PENTECOST = 11;
    /**
     * Corpus Christi (60 days after Easter)
     */
    HOLIDAY_CORPUSCHRISTI = 12;
    /**
     * First Monday after Pentecost (50 days after Easter)
     */
    HOLIDAY_WHITMONDAY = 13;
    /**
     * May, 1
     */
    HOLIDAY_MAYDAY = 14;
    /**
     * August, 15
     */
    HOLIDAY_ASSUMPTION = 15;
    /**
     * Second Tuesday of September
     */
    HOLIDAY_LABORDAY = 16;
    /**
     * October, 31
     */
    HOLIDAY_HALLOWEEN = 17;
    /**
     * November, 1
     */
    HOLIDAY_ALLSAINTSDAY = 18;
    /**
     * November, 11
     */
    HOLIDAY_ARMISTICE = 19;
    /**
     * Fourth Thursday of November
     */
    HOLIDAY_THANKSGIVING = 20;
    /**
     * December, 25
     */
    HOLIDAY_CHRISTMAS = 21;
}

message SingleDate{
	Date date = 1;
	double weight = 2;
}

message FixedDay{
	int32 month = 1;
	int32 day = 2;
	double weight = 3;
	ValidityPeriod validity = 4;
}

message EasterRelatedDay{
	int32 offset = 1;
	bool julian = 2;
	double weight = 3;
	ValidityPeriod validity = 4;
}

message PrespecifiedHoliday{
	CalendarEvent event = 1;
	int32 offset = 2;
	double weight = 3;
	ValidityPeriod validity = 4;
}

message FixedWeekDay{
	int32 month = 1;
	/* Corresponds to the first, second...)*/
	int32 position = 2;
	/* ISO-8601 standard, from 1 (Monday) to 7 (Sunday) */
	int32 weekday = 3;
	double weight = 4;
	ValidityPeriod validity = 5;
}

message CalendarDefinition{
	oneof definition{
		Calendar calendar = 1;
		WeightedCalendar  weighted_calendar = 2;
		ChainedCalendar chained_calendar = 3;
	}
}

message Calendar{
	repeated FixedDay fixed_days = 1;
	repeated EasterRelatedDay easter_related_days = 2;
	repeated FixedWeekDay fixed_week_days = 3;
	repeated PrespecifiedHoliday prespecified_holidays = 4;
	repeated SingleDate single_dates = 5;
        bool mean_correction = 10;
}

message WeightedCalendar{
	/* Weighted calendars are only defined inside a modelling context */
	message Item{
		string calendar = 1;
		double weight = 2;
	}
	repeated Item items = 1;
}

message ChainedCalendar{
	/* Chained calendars are only defined inside a modelling context */
	string calendar1 = 1;
	string calendar2 = 2;
	Date break_date = 3;
}

message TsMoniker{
	string source = 1;
	string id = 2;
}

message Ts{
        string name=1;
	TsMoniker moniker = 2;
        map<string, string> metadata= 3;
	TsData data = 4;
}

message TsCollection{
        string name=1;
	TsMoniker moniker = 2;
        map<string, string> metadata = 3;
	repeated Ts series = 4;
}

message DynamicTsData{
	TsMoniker moniker = 1;
	TsData current = 2;
}


message TsDataSuppliers{
	message Item{
		string name=1;
		oneof supplier{
			TsData data = 2;
			DynamicTsData dynamic_data = 3;
		}
	}
	repeated Item items = 1;
}

message Calendars{
	map<string, CalendarDefinition> calendars = 1;
}

message ModellingContext{
	map<string, CalendarDefinition> calendars = 1;
	map<string, TsDataSuppliers> variables = 2;
}

enum InformationType {
	Info = 0;
	Warning = 1;
	Error = 2;
}

message ProcessingDetail{
	oneof data{
		TsData ts = 1;
		Doubles array = 2;
		Matrix matrix = 3;
		StatisticalTest test = 4;
		string message = 5;
		int32 ivalue = 6;
		double dvalue = 7;
	}
}

message ProcessingInformation {
    string name = 1;
    string origin = 2;
    string msg = 3;
    InformationType type = 4;
    repeated ProcessingDetail details = 5;
}

message ProcessingLogs{
	repeated ProcessingInformation log = 1;
}

