# -*- coding: utf-8 -*-
"""
Created on Sun Jul 29 07:50:25 2018

@author: cpace
"""

import datetime

# Assign constants
MONTHCODE = {"Jan":"F","Feb":"G","Mar":"H","Apr":"J","May":"K","Jun":"M","Jul":"N","Aug":"Q","Sep":"U","Oct":"V","Nov":"X","Dec":"Z"}
MONTHNUM = ["","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
CORNMONTHS = ["Mar", "May", "Jul", "Sep", "Dec"]
BEANMONTHS = ["Jan", "Mar", "May", "Jul", "Aug", "Sep", "Nov"]
WHEATMONTHS = ["Mar", "May", "Jul", "Sep", "Dec"]
CONTRACTSYMBOLS = {"C":"cornmonths","S":"beanmonths","W":"wheatmonths"}
NUMMONTHS = 18

def DaysInMonth(year, month):
    # Function to return the length of a specified month of a specified year
    # Normally, February will have 28 days
    i = 28
    
    # If mod of the year number by 4 is zero (leap year) February will have 29 days
    if year % 4 == 0:
        i = 29
        
    # Assign the number of days per month by index key.  Datetime is one base.
    daysInMonth = [0, 31, i, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    
    # Return the number of days for the speified month
    return daysInMonth[month]

def AddMonths(startDate, months):
    # Take the month of a specified startDate and add a specified months
    endMonth = startDate.month - 1 + months

    # Take the current year number and add the endMonth // 12 which already
    # includes the part of the startYear up to the startDate
    endYear = startDate.year + endMonth // 12
    
    # Find the endMonth number of the endYear by finding the mod of the 
    # endMonth above by 12 and adding 1....it works.
    endMonth = endMonth % 12 + 1
    
    # Make sure the day of the month you are assigning as your endDate actually
    # exists.  If not, take the last day of the month (ie 2/30/23 --> 2/28/2023)
    endDay = min(startDate.day, DaysInMonth(endYear, endMonth))
    
    # Return the endDate
    return datetime.date(endYear, endMonth, endDay)

def buildMonthRange(startDate, numberMonths, startMonth=1):
    # Function builds a list of each month from specified startDate for the
    # specified numberMonths from startDate plus optional number of startMonth
    # from startDate to begin (ie startMonth = 0 will include today in list and
    # 1 will begin the list with next month.)
    monthRange = []
    for i in range(startMonth, numberMonths + 1):
        monthRange.append(AddMonths(startDate, i))
    return monthRange

def buildcontractlist(startDate, commoditySymbol, commodityMonths, use):
    if use == 2:
        prefix = "/"
    else:
        #prefix = "%2F"
        prefix = ""
    out = []
    
    # If its past the 15th, advance to next month
    if startDate.day > 15:
        startMonth = 1
    else:
        startMonth = 0
        
    for date in buildMonthRange(startDate, NUMMONTHS + startMonth, startMonth):
        displayMonth = date.month
        displayYear = date.year - 2000
        if MONTHNUM[displayMonth] in commodityMonths:
            out.append(prefix + "Z" + commoditySymbol + str(MONTHCODE[MONTHNUM[displayMonth]]) + str(displayYear))
                
    return out



def GetContracts(tradeDate):
    # x = datetime.datetime.now()
    
    out = []
    out = out + buildcontractlist(tradeDate,"C",CORNMONTHS,1)
    out = out + buildcontractlist(tradeDate,"S",BEANMONTHS,1)
    out = out + buildcontractlist(tradeDate,"W",WHEATMONTHS,1)
    return out
    
    # slash = []
    # slash = slash + buildcontractlist(x,"C",CORNMONTHS,2)
    # slash = slash + buildcontractlist(x,"S",BEANMONTHS,2)
    # slash = slash + buildcontractlist(x,"W",WHEATMONTHS,2)


