
from __future__ import absolute_import
from __future__ import division

import errno
import logging
import io

from contextlib import contextmanager
import os
import shutil
import tempfile


def touch_file(file_path):
    with open(file_path, 'a'):
        os.utime(file_path, None)


def rm_file(file_to_remove):
    try:
        os.unlink(file_to_remove)
    except OSError as e:
        if e.errno == errno.ENOENT:
            logging.warning("File: %s already removed", file_to_remove)
        else:
            logging.exception("Removing file: %s failed", file_to_remove)
            raise


@contextmanager
def atomic_file_write(filename, flag):
    fd, tmp_filename = tempfile.mkstemp(
        dir=os.path.dirname(os.path.abspath(filename)),
        prefix=os.path.basename(filename) + '.',
        suffix='.tmp')
    os.close(fd)
    try:
        if os.path.exists(filename):
            shutil.copyfile(filename, tmp_filename)
        with open(tmp_filename, flag) as f:
            yield f
    except:
        rm_file(tmp_filename)
        raise
    else:
        os.rename(tmp_filename, filename)


def rm_tree(dir_to_remove):
    try:
        shutil.rmtree(dir_to_remove)
    except OSError as e:
        if e.errno == errno.ENOENT:
            logging.warning("Directory: %s already removed", dir_to_remove)
        else:
            raise


def parse_key_val_file(file_name, delim='='):
    d = {}
    with io.open(file_name) as f:
        for line in f:
                continue
            kv = line.split(delim, 1)
            if len(kv) != 2:
                continue
            k, v = map(lambda x: x.strip(), kv)
            d[k] = v
    return d
