#!/usr/bin/env python3.6

import os
import codecs
import csv
import logging
import re
import shutil
import time

import requests

COL_PHYS_STOCK = "physicalStock"
COL_RESERVED_STOCK = "reservedStock"
COL_NET_STOCK = "netStock"

def to_num(text):
    try:
        val = int(text)
    except ValueError as ve:
        val = 0

    return val

def get_filename_from_cd(cd):
    """
    Get filename from content-disposition
    """
    if not cd:
        return ""
    fname = re.findall("filename=\"(.+)\"", cd)

    if len(fname) == 0:
        return ""

    return fname[0]


def download_inventory_file(url, path_in, default_filename):
    try:
        logging.debug("Starting download of %s", url)
        r = requests.get(url, allow_redirects=True, timeout=600)
        logging.debug("Finished download of %s", url)

        if r.status_code != 200:
            logging.warning("Server returned status {}".format(r.status_code))
            return

        filename = get_filename_from_cd(r.headers.get("content-disposition", ""))
        if len(filename) == 0:
            filename = default_filename

        full_in = os.path.join(path_in, filename)

        logging.debug("Saving data to %s", full_in)
        content_txt = r.content.decode('utf-8')
        content = content_txt.replace('\0', ' ')
        open(full_in, 'wb').write(content.encode('utf-8'))
    except Exception as ex:
        logging.error(ex)

def filter_inventory_files(source_file, target_file):
    header_read = False
    phys_stock_idx = -1
    reserv_stock_idx = -1
    net_stock_idx = -1

    with codecs.open(source_file, "r", encoding='utf-8') as f, \
            codecs.open(target_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:
                phys_stock = to_num(row[phys_stock_idx].strip())
                reserv_stock = to_num(row[reserv_stock_idx].strip())
                net_stock = to_num(row[net_stock_idx].strip())

                if phys_stock > 0 or reserv_stock > 0 or net_stock > 0:
                    writer_matched.writerow(row)
            else:
                if not COL_PHYS_STOCK in row:
                    raise Exception("Column '{}' not found in file '{}'".format(COL_PHYS_STOCK, source_file))

                if not COL_RESERVED_STOCK in row:
                    raise Exception("Column '{}' not found in file '{}'".format(COL_RESERVED_STOCK, source_file))

                if not COL_NET_STOCK in row:
                    raise Exception("Column '{}' not found in file '{}'".format(COL_NET_STOCK, source_file))

                phys_stock_idx = row.index(COL_PHYS_STOCK)
                reserv_stock_idx = row.index(COL_RESERVED_STOCK)
                net_stock_idx = row.index(COL_NET_STOCK)

                writer_matched.writerow(row)                

                header_read = True


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")
    log_file_name = 'plenty_bestand_' + time.strftime("%Y%m%d-%H%M%S") + '.log'
    log_file = os.path.join(path_log, log_file_name)
    logging.basicConfig(level=logging.DEBUG,
        format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] : %(message)s",
        handlers=[
            logging.FileHandler(log_file),
            logging.StreamHandler()
        ])            

    files = os.listdir(path_in)
    num_files = len(files)

    logging.debug("Found {0} files...".format(num_files))

    if num_files == 0:
        # Let's try down load files
        download_inventory_file("https://www.sport-versand24.de/export/2/fdnVrBx5UzqOzCOr07h7eIp9Tk1QdtrY", path_in, "bestand_lager_9.csv")
        download_inventory_file("https://www.sport-versand24.de/export/3/KIE0kiepZbOGWhbl7UHV7eVw2q5fTGhj", path_in, "bestand_lager_12.csv")

    files = os.listdir(path_in)
    num_files = len(files)

    logging.debug("Found {0} files...".format(num_files))

    if num_files == 0:
        return

    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):
            msg = "Matching Plenty IDs {0}...".format(in_file)
            logging.debug(msg)

            try:
                filter_inventory_files(in_file, out_file)
                shutil.move(in_file, prc_file)
            except Exception as e:
                logging.error(e)
                print("Error : {}".format(e))
                shutil.move(in_file, err_file)


def main():
    data_root = r"/ftproot/"
    # data_root = r"/home/holger/git/bitbucket/thelen/data/"
    # data_root = r"c:/temp/thelen/"

    invoice_data_root = os.path.join(data_root, "Matching_Plenty_Bestand")
    process_files(invoice_data_root)

if __name__ == "__main__":
    main()
