#!/usr/bin/env python
"""
Convert a weatherlink export file to pthelma timeseries format.

weatherlinkexport2pthelmats export_file [timezone]

This program reads the export file and outputs one file for each
variable present in the weatherlink export file. The names of the
output files are taken from the headings. The date should be in
YYYY-MM-DD and the time in 24-hour clock format, where midnight is
00:00.

If timezone is specified, it also corrects the timestamps for DST, so,
for example, if timezone is Europe/Athens and the export file contains
a timestamp of 2014-04-05 15:00, this will be converted to 2014-04-05
14:00 in the output. It won't work for ambiguous times.

The purpose of this program is to prepare data for unit testing
purposes.
"""

import sys
from datetime import datetime

import pytz


class WeatherLinkExportFile(object):
    wind_dir_symbols = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
                        'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW',]

    def __init__(self, filename, timezone):
        self.filename = filename
        self.timezone = pytz.timezone(timezone)

    def __enter__(self):
        self.fp = open(self.filename)
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.fp.close()

    def read_headings(self):
        self.fp.seek(0)
        line1 = self.fp.readline()
        line2 = self.fp.readline()
        headings1 = [x.strip().replace(' ', '-')
                     for x in line1.split('\t')[2:]]
        headings2 = [x.strip().replace(' ', '-')
                     for x in line2.split('\t')[2:]]
        self.filenames = ['{0}-{1}'.format(h1, h2).replace('.', '')
                          .strip('-').lower() + '.txt'
                          for h1, h2 in zip(headings1, headings2)]

    def fix_dst(self, date, time):
        year, month, day = [int(x) for x in date.split('-')]
        hour, minute = [int(x) for x in time.split(':')]
        adatetime = datetime(year, month, day, hour, minute)
        adatetime -= self.timezone.dst(adatetime)
        date, time = adatetime.isoformat().split('T')
        time, d, d = time.rpartition(':')  # Remove seconds
        return date, time

    def create_output_files(self):
        fps = [open(filename, 'w') for filename in self.filenames]
        self.fp.seek(0)
        for i, line in enumerate(self.fp):

            # Skip first two lines
            if i < 2:
                continue

            items = line.strip().split('\t')
            date = items.pop(0)
            time = items.pop(0)
            date, time = self.fix_dst(date, time)
            for item, fp, fn in zip(items, fps, self.filenames):
                if '-speed' in fn:
                    value = '{0:.1f}'.format(self.kmh2ms(float(item)))
                elif '-dir' in fn:
                    value = (self.wind_dir_symbols.index(item) * 22.5
                             if item in self.wind_dir_symbols else '')
                else:
                    value = item
                fp.write('{0}T{1},{2},\n'.format(date, time, value))
        [fp.close() for fp in fps]

    def process(self):
        self.read_headings()
        self.create_output_files()

    def kmh2ms(self, value):
        """Convert km/h of wind speed to m/s"""

        # First find what the original was in mph
        mph = round(value / 1.609344, 0)

        # Then convert that to m/s
        return mph * 1609.344 / 3600

export_file = sys.argv[1]
timezone = 'UTC' if len(sys.argv) <= 2 else sys.argv[2]
with WeatherLinkExportFile(export_file, timezone) as w:
    w.process()
