#!/usr/bin/env python

import os
import codecs
import csv
import logging
import shutil
import time

__author__ = 'holger'

def is_price_file(file_path):
    with codecs.open(file_path, "rb", encoding='utf-8') as f:
        reader = csv.reader(f, delimiter='\t')
        if reader:
            try:
                for row in reader:
                    if row:
                        return "item-price" in row and "shipping-price" in row and "amazon-order-id" in row

            except Exception as e:
                logging.error(e)

def read_price_dict(price_file_path):
    price_dict = dict()

    header_read = False

    order_id_index = -1
    sku_index = -1
    item_price_index = -1
    ship_price_index = -1

    with codecs.open(price_file_path, "rb", encoding='cp1252') as f:
        reader = csv.reader(f, delimiter='\t')
        for row in reader:
            if header_read:
                order_id = row[order_id_index]
                sku = row[sku_index]
                item_price = row[item_price_index]
                ship_price = row[ship_price_index]

                if len(order_id) > 0 and len(sku) > 0 and len(item_price) > 0:
                    combo_key = order_id + "-" + sku
                    if not combo_key in price_dict:
                        price_dict[combo_key] = [item_price, ship_price]
                    else:
                        logging.error("Duplicate combo key {0}".format(combo_key))
                        raise Exception("Found duplicate order id/sku combination")
            else:
                order_id_index = row.index("amazon-order-id")
                sku_index = row.index("sku")
                item_price_index = row.index("item-price")
                ship_price_index = row.index("shipping-price")

                header_read = True

    return price_dict

def merge_buyers_with_prices(buyer_file_path, out_file_path, price_dict):
    order_id_index = -1
    sku_index = -1
    header_read = False

    with codecs.open(buyer_file_path, "r", encoding='cp1252') as f, \
            codecs.open(out_file_path, "w", encoding='cp1252') as of:
        reader = csv.reader(f, delimiter='\t')
        writer = csv.writer(of, delimiter='\t')
        for row in reader:
            if any(row):
                write_row = True
                if header_read:
                    order_id = row[order_id_index]
                    sku = row[sku_index]

                    combo_key = order_id + "-" + sku

                    if combo_key in price_dict:
                        price_pair = price_dict[combo_key]
                        row.append(price_pair[0])
                        row.append(price_pair[1])
                    else:
                        write_row = False
                else:
                    header_read = True
                    if "order-id" in row:
                        order_id_index = row.index("order-id")
                    if "sku" in row:
                        sku_index = row.index("sku")

                    if order_id_index < 0:
                        logging.error("Could not find order-id column.")
                        raise Exception("No column to match found. Aborting...")
                    else:
                        row.append("item-price")
                        row.append("shipping-price")

                if write_row:
                    writer.writerow(row)

def process_files(data_root):
    path_in = os.path.join(data_root, "in")
    path_out = os.path.join(data_root, "out")
    path_prc = os.path.join(data_root, "processed")
    path_err = os.path.join(data_root, "error")
    path_log = os.path.join(data_root, "log")

    # Set up logging
    log_file_name = time.strftime("%Y%m%d-%H%M%S") + '.log'
    log_file = os.path.join(path_log, log_file_name)
    logging.basicConfig(filename=log_file, level=logging.DEBUG)

    files = os.listdir(path_in)
    num_files = len(files)

    logging.info("Found {0} files...".format(num_files))

    if num_files == 0:
        return

    if num_files != 2:
        if num_files > 2:
            logging.error("Too many input files. Exactly 2 input files are required.")
        else:
            logging.error("Exactly 2 input files are required. Only 1 was found.")
        return

    if is_price_file(os.path.join(path_in, files[0])):
        price_file_name = files[0]
        buyer_file_name = files[1]

    elif is_price_file(os.path.join(path_in, files[1])):
        price_file_name = files[1]
        buyer_file_name = files[0]
    else:
        logging.error("Could not identify price file. Aborting...")
        return

    output_file_name = os.path.splitext(buyer_file_name)[0] + '.txt'

    price_file = os.path.join(path_in, price_file_name)
    buyer_file = os.path.join(path_in, buyer_file_name)
    out_file = os.path.join(path_out, output_file_name)
    prc_buyer_file = os.path.join(path_prc, buyer_file_name)
    prc_price_file = os.path.join(path_prc, price_file_name)
    err_buyer_file = os.path.join(path_err, buyer_file_name)
    err_price_file = os.path.join(path_err, buyer_file_name)

    if os.path.isfile(price_file) and os.path.isfile(buyer_file):
        logging.debug("Merging Amazon Order Report {0}...".format(buyer_file_name))
        try:
            price_dict = read_price_dict(price_file)
            merge_buyers_with_prices(buyer_file, out_file, price_dict)
            shutil.move(price_file, prc_price_file)
            shutil.move(buyer_file, prc_buyer_file)
            pass
        except Exception as e:
            logging.error(e)
            shutil.move(price_file, err_price_file)
            shutil.move(buyer_file, err_buyer_file)

def main():
    data_root = r"/ftproot/"
    #data_root = r"/data/projects/pycharm/thelen/conversion/data/"
    #data_root = r"c:/temp/thelen/"
    data_root = r"/ftproot/"
	
    dupe_data_root = os.path.join(data_root, "Matching_Bestellberichte")
    process_files(dupe_data_root)

if __name__ == "__main__":
    main()