#!/usr/bin/env python

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

__author__ = 'holger'


def read_ref(ref_path, ref_file):
    # Expects ref_file to exist in ref folder
    ref_dict = {}

    header_read = False

    full_ref_path = os.path.join(ref_path, ref_file)
    ean_index = -1
    loc_index = -1
    lid_index = -1
    stk_index = -1
    rst_index = -1
    whs_index = -1

    with codecs.open(full_ref_path, "r", encoding='utf-8', errors='ignore') as f:
        reader = csv.reader(f, delimiter=';')
        for row in reader:
            # print(row)
            if header_read:
                try:
                    stock_qty = float(row[stk_index].replace(",", "."))
                    resvd_qty = float(row[rst_index].replace(",", "."))
                    if stock_qty - resvd_qty > 0:
                        ref_dict[row[ean_index]] = (row[loc_index], row[lid_index], row[whs_index])
                except Exception as ex:
                    msg = "Quantity conversion from {} failed for EAN {} and stock qty {} and " \
                          + " reserved qty {}"
                    logging.warning(msg.format(row[ref_file, ean_index, row[stk_index], row[rst_index]]))
                    logging.error(ex)
            else:
                if "VariationEAN" in row:
                    ean_index = row.index("VariationEAN")
                if "LocationName" in row:
                    loc_index = row.index("LocationName")
                if "LocationID" in row:
                    lid_index = row.index("LocationID")
                if "WarehouseID" in row:
                    whs_index = row.index("WarehouseID")
                if "Stock" in row:
                    stk_index = row.index("Stock")
                if "ReservedStock" in row:
                    rst_index = row.index("ReservedStock")

                if ean_index < 0 or loc_index < 0 or stk_index < 0 or rst_index < 0 or whs_index < 0 or lid_index < 0:
                    raise Exception("Not all columns found in {}".format(ref_file))

                header_read = True

    return ref_dict


def create_order_file(in_file, out_file, ref_fo, ref_sh, ref_ssw):
    header_read = False
    ean_index = -1
    loc_index = -1

    with codecs.open(in_file, "r", encoding='utf-8') as f, codecs.open(out_file, "w", encoding='utf-8') as of:
        reader = csv.reader(f, delimiter=';')
        writer = csv.writer(of, delimiter=';')

        for row in reader:
            if any(row):
                if header_read:
                    ean = row[ean_index]

                    if ean in ref_fo:
                        row[loc_index] = row[loc_index] + ' ## ' + ref_fo[ean][0]
                        row = row + [ref_fo[ean][1],ref_fo[ean][2]]
                    elif ean in ref_sh:
                        row[loc_index] = row[loc_index] + ' ## ' + ref_sh[ean][0]
                        row = row + [ref_sh[ean][1],ref_sh[ean][2]]
                    elif ean in ref_ssw:
                        row[loc_index] = row[loc_index] + ' ## ' + ref_ssw[ean][0]
                        row = row + [ref_ssw[ean][1],ref_ssw[ean][2]]

                    writer.writerow(row)
                else:
                    if "RowItemExternalID" in row:
                        ean_index = row.index("RowItemExternalID")
                    if "RowItemText" in row:
                        loc_index = row.index("RowItemText")

                    if ean_index < 0 or loc_index < 0:
                        raise Exception("Not all columns found in input file {}".format(in_file))

                    header_read = True
                    writer.writerow(row + ["LocationId", "WarehouseId"])


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_ref = os.path.join(data_root, "ref")
    path_err = os.path.join(data_root, "error")
    path_log = os.path.join(data_root, "log")

    # Set up logging
    datetime_file_name = time.strftime("%Y%m%d-%H%M%S")
    log_file_name = datetime_file_name + '.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

    # Read SO ref
    ref_fo = read_ref(path_ref, "Vendor_Abgleich_FO.csv")

    # Read SH ref
    ref_sh = read_ref(path_ref, "Vendor_Abgleich_SH.csv")

    # Read SSW ref
    ref_ssw = read_ref(path_ref, "Vendor_Abgleich_SSW.csv")

    for f in files:
        in_file = os.path.join(path_in, f)
        proc_file = os.path.join(path_prc, f)
        err_file = os.path.join(path_err, f)

        out_file_name = os.path.splitext(f)[0] + ".csv"
        out_file = os.path.join(path_out, out_file_name)

        if os.path.isfile(in_file):
            try:
                logging.debug("Processing {0}...".format(in_file))

                create_order_file(in_file, out_file, ref_fo, ref_sh, ref_ssw)

                if os.path.isfile(in_file):
                    shutil.move(in_file, proc_file)

            except Exception as e:
                logging.error(e)

                # Move in file to error
                shutil.move(in_file, err_file)


def main():
    data_root = r"/ftproot/"
    # data_root = r"/home/holger/git/thelen/data/"
    # data_root = r"c:/temp/thelen/"

    data_root = os.path.join(data_root, "Matching_Vendor_Bestellungen")
    process_files(data_root)


if __name__ == "__main__":
    main()

