#!/usr/bin/env python3.6

import os
import codecs
import csv
import logging
import logging.config
import shutil

import common 

HDR_VAR_ID = "VariationID"
HDR_EAN = "Code"

logger = None

def read_var_id_lookup(ref_path):
    ref_dict = {}
    variation_id_idx = -1
    first_header_read = False

    files = sorted(os.listdir(ref_path))
    for f in files:
        logger.info(f"Reading ref {f}")
        full_ref_path = os.path.join(ref_path, f)

        header_read = False
        # full_ref_path = os.path.join(ref_path, "Ref_VariationBarcode.csv")
        with codecs.open(full_ref_path, "rb", encoding='utf-8') as f:
            reader = csv.reader(f, delimiter=';')

            for row in reader:
                if header_read:
                    variation_id = row.pop(variation_id_idx)
                    variation_id = variation_id.strip()

                    if variation_id in ref_dict:
                        logger.warning("Found duplicate VariationID %s in ref.", variation_id)

                    ref_dict[variation_id] = row
                else:
                    if not HDR_VAR_ID in row:
                        raise Exception("Column '{}' not found in ref file '{}'.".format(HDR_VAR_ID, f))

                    if not HDR_EAN in row:
                        raise Exception("Column '{}' not found in ref file '{}'".format(HDR_EAN, f))

                    if not first_header_read:
                        variation_id_idx = row.index(HDR_VAR_ID)
                        row.pop(variation_id_idx)
                        hdr_names = row
                        first_header_read = True

                    header_read = True

    return ref_dict, hdr_names

def match_variation_ids(source_file, matched_file, ref_dict, headers):
    header_read = False
    variation_id_idx = -1
    ean_idx = -1

    with codecs.open(source_file, "r", encoding='utf-8') as f, \
            codecs.open(matched_file, "w", encoding='utf-8') as of:

        reader = csv.reader(f, delimiter=';')
        writer_matched = csv.writer(of, delimiter=';', quoting=csv.QUOTE_NONNUMERIC)

        for row in reader:
            if header_read:
                variation_id = row[variation_id_idx].strip()
                if variation_id in ref_dict:
                    ean = row[ean_idx]                    
                    if ean:
                        ean = ean.strip()
                        ean_cols = [ean + "-sv24" , ean + "-myo", ean + "-c4b", ean + "-schi", ean + "-out24"]
                    else:
                        ean_cols = [ "", "", "", "", ""]

                    writer_matched.writerow(row + ref_dict[variation_id] + ean_cols)
            else:
                if not HDR_VAR_ID in row:
                    raise Exception("Column '{}' not found in file '{}'".format(HDR_VAR_ID, source_file))


                variation_id_idx = row.index(HDR_VAR_ID)
                ean_idx = headers.index(HDR_EAN)
                # Add columns -sv24 , -myo, -c4b , -schi and -out24
                ean_hdrs = ["ean-sv24", "ean-myo", "ean-c4b", "ean-schi", "ean-out24"]

                writer_matched.writerow(row + headers + ean_hdrs)

                header_read = True


def process_files(data_root):
    global logger

    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_ref = os.path.join(data_root, "ref")
    path_log = os.path.join(data_root, "log")

    log_file = os.path.join(path_log, os.path.basename(__file__) + ".log")
    logging.config.dictConfig(common.get_logging_config(log_file))

    logger = logging.getLogger(__file__)

    files = os.listdir(path_in)
    num_files = len(files)

    logger.info("Found {0} file(s)...".format(num_files))

    if num_files == 0:
        return

    ean_ref, ref_headers = read_var_id_lookup(path_ref)

    for f in files:
        in_file = os.path.join(path_in, f)
        out_file = os.path.join(path_out, f)
        prc_file = os.path.join(path_prc, f)
        err_file = os.path.join(path_err, f)

        if os.path.isfile(in_file):
            logger.info("Matching Plenty IDs %s...", in_file)

            try:
                match_variation_ids(in_file, out_file, ean_ref, ref_headers)
                shutil.move(in_file, prc_file)
            except Exception as e:
                logger.error(e)
                print("Error : {}".format(e))
                shutil.move(in_file, err_file)
    
    logger.info("Finished")


def main():
    if os.path.exists(r"/ftproot/"):
        data_root = r"/ftproot/"
    elif os.path.exists(r"/home/holger/git/bitbucket/thelen/data/"):
        data_root = r"/home/holger/git/bitbucket/thelen/data/"
    else:
        print("Unknown environment. Please set data_root to data folder location. Aborting.")
        return

    script_data_root = os.path.join(data_root, "Matching_Plenty_ID")

    process_files(script_data_root)

if __name__ == "__main__":
    main()
