#! /usr/bin/python
# -*-coding:utf-8-*-

import sys
import requests
from lxml import html
import time
import datetime
import os
import argparse

from xiaoming_weather import smartutils

defaultencoding = 'utf-8'

if sys.getdefaultencoding() != defaultencoding:
    reload(sys)
    sys.setdefaultencoding(defaultencoding)

def setEncodingToUtf8():
    '''
    The system default encoding is ASCII.
    url date error 'ascii' codec can't decode byte 0xe4 in position 4: ordinal not in range(128)
    '''
    defaultencoding = 'utf-8'
    if sys.getdefaultencoding() != defaultencoding:
        reload(sys)
        sys.setdefaultencoding(defaultencoding)
    return

class Weather(object):
    '''
    Get weather data from http://www.weather.com.cn/weather/%s.shtml
    Save weather data to local file.
    '''
    
    def __init__(self,cityCode,historyFile = None):
        
        #init history.db file
        self.historyFile = "history.db"

        #init city code
        self.cityCode = cityCode
        
        #init string source from weather website.
        self.content = self.getContent(self.cityCode)
        self.sel = html.fromstring(self.content)
        #top type list
        self.top = self.sel.xpath('//ul[@class="t clearfix"]')[0]
      
    def getContent(self, cityCode):
        url = 'http://www.weather.com.cn/weather/%s.shtml' % cityCode
        return requests.get(url).content

    def getTemp(self, top, day_index):

        tempLow = top.xpath('li[%d]/p[@class="tem"]/i/text()' % day_index)[0]
        if len(top.xpath('li[%d]/p[@class="tem"]/span' % day_index)) != 0:
            tempHigh = top.xpath('li[%d]/p[@class="tem"]/span/text()' % day_index)[0]
        
        if '℃' in tempLow:
            tempLow = tempLow.replace('℃', '')
        
        if tempHigh:
            if '℃' in tempHigh:
                tempHigh = tempHigh.replace('℃', '')
                 
        if tempHigh:
            temp = tempLow + ',' + tempHigh
        else:
            #to ensure a formatable record
            temp = tempLow + ',' + 'null'
        return temp

    
    def getContinusDay(self, days):
        ''''
        Print the following %days weather data, including today
        
        Return 'Date：%s\nWeather：%s\nTemp：%s\nWind：%s'
        '''
        for i in range(1, days+1):
            date = self.top.xpath('li[%d]/h1/text()' % i)[0]
            weather = self.top.xpath('li[%d]/p[@class="wea"]/text()' % i)[0]
            tem = self.getTemp(self.top, i)
            wind = self.top.xpath('li[%d]/p[@class="win"]/i/text()' % i)[0]
            print(u'Date：%s\nWeather：%s\nTemp：%s\nWind：%s' % (date, weather, tem, wind))
            print ("="*30)
        return
 
    def getSepcificDay(self, day):
        '''
        Day 1 means return the temp of today, day 2 is the temp of tomorrow.
        
        Return format: weatherData{date,weather,temp,wind}
        '''
        date = self.top.xpath('li[%d]/h1/text()' % day)[0]
        weather = self.top.xpath('li[%d]/p[@class="wea"]/text()' % day)[0]
        temp = self.getTemp(self.top, day)
        wind = self.top.xpath('li[%d]/p[@class="win"]/i/text()' % day)[0]
        weatherData = {"date" : date, \
                "weather" : weather, \
                 "temp" : temp, \
                 "wind" : wind \
                }
        return weatherData
 
    def readHistoryTempData(self):
        '''
        Read last line from history.db.
        If not found history data on the local meachine, that means it's the firts time running of this app. then, return a default 'null,null'
  
        Retrun 'lowTemp,highTemp'
        
        '''
        lastLine = ""
        if os.path.exists(self.historyFile):
            with open(self.historyFile,"rb") as fr:
                offset = -4  #set offset
                while True:
                    fr.seek(offset, 2)
                    lines = fr.readlines()
                    #at least read one line
                    if len(lines) >= 2:
                        lastLine = lines[-1]
                        break
                    offset *= 2
        
        if lastLine:
            lastLine = lastLine.strip()
            temp = lastLine.split(':')[1]
            return temp
        
        return 'null,null'

    def appendHistory(self, tempData):
        '''
        Save Weather temp histroy data to local file as a plain text file.
        return 0 success
        '''
        
        #init history.db file
        if not os.path.exists(self.historyFile):
            print ('Not found histroy.db,creating it...')
            fp = open(self.historyFile,"w")
            fp.write('#Weather temp data file using to save tempareture data.\n')
            fp.write("#It is auto generated by zhangyd, please don't modify it.\n")
            fp.flush()
            fp.close()
        
        with open(self.historyFile,'a') as fw:
            today = datetime.date.today()
            content = str(today) + ":" + tempData + "\n"
            fw.write(content)
        
        return 0

class XiaoMingWeather(object):
    '''
    Generate common weather string.

    Return XiaoMingWeather(weatherDataToday, weatherDataTomorow).weatherMsg
    '''
    
    _HIGH_TEMP_ALERT = 35
    _VERY_HIGH_TEMP_ALERT = 40
    _VERY_LOW_TEMP_ALERT = -15
    _HUGE_LOW_HIGH = 15
    _HILL_TEMP = 5
    
    Spring = [3,4,5]
    Summer = [6,7,8]
    Fall = [9,10,11]
    Winter = [12,1,2]
    
    def __init__(self, weatherDataToday, weatherDataTomorow):
        self.weatherDataToday = weatherDataToday
        self.weatherDataTomorow = weatherDataTomorow
        
        #debug
        #self.weatherDataToday = '6,40'
        #self.weatherDataTomorow['temp'] = '7,41'
        
        self.weather_title = '小明天气：今天' + self.weatherDataToday.split(',')[0] + '℃~' + self.weatherDataToday.split(',')[1] + '℃' + '，明天' + self.weatherDataTomorow["weather"] + self.TomorowSuggestions() + self.HolidaysInfo()
        self.weatherMsg = \
                 self.weather_title \
                 + '\n明天: ' + self.weatherDataTomorow['weather'] \
                 + '\n温度: ' + self.weatherDataTomorow['temp'].split(',')[0] + '℃~' + self.weatherDataTomorow['temp'].split(',')[1] + '℃' \
                 + '\n风力: ' + self.weatherDataTomorow['wind']

    def TomorowSuggestions(self):
        '''
        Canculate suggestiong string.
        If 'null' in any of weather data. return ''.
        '''
        
        TomorowSuggestions = ''
        
        if 'null' in self.weatherDataToday:
            return TomorowSuggestions
        
        if 'null' in self.weatherDataTomorow:
            return TomorowSuggestions
        
        todayLow = int(self.weatherDataToday.split(',')[0])
        todayHigh = int(self.weatherDataToday.split(',')[1])
        
        tomorowLow = int(self.weatherDataTomorow['temp'].split(',')[0])
        tomorowHigh = int(self.weatherDataTomorow['temp'].split(',')[1])
        
        
        #cancluate tempareture rise and down string.
        rise = ''
        drop = ''
        
        if self.isSpring():
            rise = '，温度适宜'
            drop = '，比今天冷一点'
        elif self.isSummer():
            rise = '，比今天热一些'
            drop = '，比今天凉快一些'
        elif self.isFall():
            rise = '，秋高气爽，温度适宜'
            drop = '，比今天凉一点'
        elif self.isWinter():
            rise = '，比今天暖和一点'
            drop = '，比今天冷一点'
        else:
            pass

        if tomorowHigh >= todayHigh:
            if tomorowLow >= todayLow:
               TomorowSuggestions = TomorowSuggestions + rise
        else:
            if tomorowLow <= todayLow:
               TomorowSuggestions = TomorowSuggestions + drop

        if tomorowHigh < todayHigh:
            if abs(tomorowHigh - todayHigh) > XiaoMingWeather._HILL_TEMP:
                TomorowSuggestions = TomorowSuggestions + '，似乎要降温了'
            else: 
                if abs(tomorowLow - todayLow) > XiaoMingWeather._HILL_TEMP:
                    TomorowSuggestions = TomorowSuggestions + '，似乎要降温了'
        
        if tomorowHigh - tomorowLow > XiaoMingWeather._HUGE_LOW_HIGH:
            TomorowSuggestions = TomorowSuggestions + '，早晚温差比较大'
        
        if tomorowHigh >= XiaoMingWeather._HIGH_TEMP_ALERT:
            TomorowSuggestions = TomorowSuggestions + '，高温天气'
               
        if tomorowHigh >= XiaoMingWeather._VERY_HIGH_TEMP_ALERT:
            TomorowSuggestions = TomorowSuggestions + '，高温40度，请注意防暑'
        
        if tomorowLow < XiaoMingWeather._VERY_LOW_TEMP_ALERT:
            TomorowSuggestions = TomorowSuggestions + '，低温天气,请注意保暖'

        return TomorowSuggestions + '。'
        
        
    def HolidaysInfo(self):
        HolidaysInfo = ''
        if smartutils.DateTime().isHolidaysComing():
            HolidaysInfo = '要放假了，节后见~'
        return HolidaysInfo
        
        
    def isSpring(self):
        today=datetime.date.today()
        if today.month in self.Spring:
            return True
        return False
        
    def isSummer(self):
        today=datetime.date.today()
        if today.month in self.Summer:
            return True
        return False

    def isFall(self):
        today=datetime.date.today()
        if today.month in self.Fall:
            return True
        return False

    def isWinter(self):
        today=datetime.date.today()
        if today.month in self.Winter:
            return True
        return False

def testXiaoMingWeather():
    #xi'an city code is 101110101
    xaweather = Weather('101110101')
    
    #getSepcificDay date
    weatherDataTomorow = xaweather.getSepcificDay(2)
    weatherDataToday = xaweather.readHistoryTempData()
    print (XiaoMingWeather(weatherDataToday, weatherDataTomorow).weatherMsg)


def main():
    #parser object
    parser = argparse.ArgumentParser(description = 'XiaoMing Weather')

    parser.add_argument("-q", "--query", type = str, nargs = 1, 
                        metavar = "city-code", default = None, help = "The specific city code from http://www.weather.com.cn")

    # parse the arguments from standard input 
    args = parser.parse_args()

    if args.query == None:
        #default set to city Xi'an 
        cityCode = '101110101'
    else:
        cityCode = args.query[0]

    #init weather object
    weather = Weather(cityCode)

    #getSepcificDay date
    weatherDataTomorow = weather.getSepcificDay(2)
    weatherDataToday = weather.readHistoryTempData()

    #print weather msg to stdout
    print (XiaoMingWeather(weatherDataToday, weatherDataTomorow).weatherMsg)

if __name__ == '__main__':
    main()
    exit(0)