""" Shared utility functions """
import json
import logging
import logging.config
import os
import sys
import time
from typing import Any, Dict, List, Optional

DATA_ROOT_PROD = "/ftproot/"
DATA_ROOT_DEV = "/home/holger/git/bitbucket/thelen/data/"


def get_data_root() -> str:
    """ Find data root folder by checking known paths.
    Returns:
        path to folder or exits with non-zero return value
    """
    data_root = None
    if os.path.exists(DATA_ROOT_PROD):
        data_root = DATA_ROOT_PROD
    elif os.path.exists(DATA_ROOT_DEV):
        data_root = DATA_ROOT_DEV
    else:
        print("Unknown environment. Cannot locate data root folder. Aborting.")
        sys.exit(1)

    return data_root


def get_script_folder() -> str:
    """Path of current script.
    Returns:
        path as string
    """
    return os.path.dirname(os.path.realpath(__file__))


def get_logging_config(rotate_filename=None) -> Optional[Dict[str, Any]]:
    """Load logging config and inject the rotating log filename if set
    Returns:
        config dict
    """
    config = None

    log_cfg_file = os.path.join(get_script_folder(), "logging.json")

    if not os.path.isfile(log_cfg_file):
        print("Logging config file {} not found.".format(log_cfg_file))
        return None

    try:
        with open(log_cfg_file, "r") as f:  # pylint: disable=invalid-name
            config = json.load(f)

        handler = config.get("handlers").get("rotate")
        if handler:
            handler["filename"] = rotate_filename

    except Exception as ex:  # pylint: disable=broad-except
        print(ex)

    return config


def get_column_index_csv(row: list, col_name: str) -> int:
    """Lookup column index by name case-insensitive.

    Returns:
        Column index (int) or -1 if not found.
    """
    column_idx = -1
    if col_name and row:
        row_lower = [
            x.lower() if x and isinstance(x, str) else '' for x in row
        ]
        col_name_lower = col_name.lower()

        if col_name_lower in row_lower:
            column_idx = row_lower.index(col_name_lower)

    return column_idx


def setup_logging(log_path: str) -> None:
    """ Set up logging to STDOUT and log file. """

    log_file = os.path.join(log_path,
                            '{}.log'.format(time.strftime("%Y%m%d-%H%M%S")))

    logging.config.dictConfig({
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
            },
        },
        'handlers': {
            'default': {
                'level': 'NOTSET',
                'class': 'logging.StreamHandler',
                'formatter': 'standard'
            },
            'logfile': {
                'filename': log_file,
                'class': 'logging.FileHandler',
                'formatter': 'standard'
            }
        },
        'loggers': {
            '': {
                'handlers': ['default', 'logfile'],
                'level': 'NOTSET',
                'propagate': True
            }
        }
    })


def parse_money(amount_txt: str) -> float:
    """ Parse money. Mostly parsing Euros, so replace "," with "." first """
    val = 0.0
    try:
        val = float(amount_txt.replace(",", "."))
    except ValueError as ve:  # pylint: disable=invalid-name
        logging.exception(ve)

    return val


def pad_row(row: List[Any],
            desired_length: int,
            pad_left: bool = False,
            pad_with: Any = None) -> List[Any]:
    """ Pad list with extra """
    if not row or not isinstance(row, list):
        return row
    if len(row) < desired_length:
        padding = [pad_with] * (desired_length - len(row))

        return padding + row if pad_left else row + padding

    return row
