# -*- coding: utf-8 -*-
"""
    File name:      load_data_act.py
    Author:         Tetsuro Tatsuoka
    Date created:   04/12/2018
    Last modified:  04/12/2018
    Version:        1.0.0
    Python version: 3.6.3
    Description:    Load data of activity of daily living (ADL)
                     from UCI Machine Learning Repository
    Reference:
        Activities of Daily Living (ADLs) Recognition Using Binary Sensors Data Set
        https://archive.ics.uci.edu/ml/datasets/Activities+of+Daily+Living+(ADLs)+Recognition+Using+Binary+Sensors

    Revision history:
        1.0.0   04/12/2018  - Initial coding.
"""
import pandas as pd
import numpy as np
import os
import requests
import zipfile

ZIP_URL = 'https://archive.ics.uci.edu/ml/machine-learning-databases/00240/UCI HAR Dataset.zip'
DATADIR = 'UCI HAR Dataset'

SIGNALS = [
    "body_acc_x",
    "body_acc_y",
    "body_acc_z",
    "body_gyro_x",
    "body_gyro_y",
    "body_gyro_z",
    "total_acc_x",
    "total_acc_y",
    "total_acc_z"
]


def download_file(url):
    """ Download file from the URL
    """
    filename = url.split('/')[-1]
    r = requests.get(url, stream=True)
    with open(filename, 'wb') as f:
        for chunk in r.iter_content(chunk_size=1024):
            if chunk:
                f.write(chunk)
                f.flush()
        return filename
    
    # Return False when error occurs
    return False

def zip_extract(filename):
    """ Extract zip file on the current directory
    """
    target_directory = '.'
    zfile = zipfile.ZipFile(filename)
    zfile.extractall(target_directory)


def _read_csv(filename):
    return pd.read_csv(filename, delim_whitespace=True, header=None)

def load_signals(subset):
    signals_data = []

    for signal in SIGNALS:
        filename = f'{DATADIR}/{subset}/Inertial Signals/{signal}_{subset}.txt'
        signals_data.append(
            _read_csv(filename).as_matrix()
        ) 

    # Transpose is used to change the dimensionality of the output,
    # aggregating the signals by combination of sample/timestep.
    # Resultant shape is (7352 train/2947 test samples, 128 timesteps, 9 signals)
    return np.transpose(signals_data, (1, 2, 0))

def load_y(subset):
    """
    The objective that we are trying to predict is a integer, from 1 to 6,
    that represents a human activity. We return a binary representation of 
    every sample objective as a 6 bits vector using One Hot Encoding
    (https://pandas.pydata.org/pandas-docs/stable/generated/pandas.get_dummies.html)
    """
    filename = f'{DATADIR}/{subset}/y_{subset}.txt'
    y = _read_csv(filename)[0]

    return pd.get_dummies(y).as_matrix()

def load_data():
    """ Load data from Web site and return X_train, X_test, y_train, y_test
    """
    if not os.path.exists(DATADIR):
        filename = download_file(ZIP_URL)
        if filename:
            print('{} is downloaded.'.format(filename))
            zip_extract(filename)
            print('{} is extracted.'.format(filename))
        else:
            print('{} cannot be downloaded.'.format(filename))
            X_train = None
            X_test = None
            y_train = None
            y_test = None

    X_train, X_test = load_signals('train'), load_signals('test')
    y_train, y_test = load_y('train'), load_y('test')

    return X_train, X_test, y_train, y_test
