# This file is part of the Reproducible Open Benchmarks for Data Analysis
# Platform (ROB).
#
# Copyright (C) 2019 NYU.
#
# ROB is free software; you can redistribute it and/or modify it under the
# terms of the MIT License; see LICENSE file for more details.

"""The reproducible benchmark engine uses a simple file store to maintain files
that are uploaded by users as part of the inputs to workflow runs.

Uploaded files are currently stored on disk. The file store maintains uploaded
files within sub-folders of a base folder. Each file has a unique identifier
that is generated by the system. The file handle is a wrapper around the local
file to provide access to the file.
"""

import os
from datetime import datetime

from benchtmpl.util.core import get_unique_identifier


class FileHandle(object):
    """Handle for files that are managed by the file store. Each file has a
    unique identifier and a file name. Files are maintaind in folders on the
    file system.
    """
    def __init__(self, filepath, identifier=None, file_name=None):
        """Initialize the file identifier, the (full) file path, and the file
        name. The file path is mandatory.

        Parameters
        ----------
        filepath: string
            Absolute path to file on disk
        identifier: string, optional
            Unique file identifier
        file_name: string, optional
            Base name of the file
        """
        self.filepath = os.path.abspath(filepath)
        self.identifier = identifier if not identifier is None else get_unique_identifier()
        self.file_name = file_name if not file_name is None else os.path.basename(self.filepath)

    @property
    def created_at(self):
        """Date and time when file was created (e.g., uploaded). The timestamp
        is given in the UTC time zone.

        Returns
        -------
        datetime.date
        """
        return datetime.utcfromtimestamp(os.path.getctime(self.filepath))

    @property
    def name(self):
        """Method for accessing the file name.

        Returns
        -------
        string
        """
        return self.file_name

    @property
    def size(self):
        """Get size of file in bytes.

        Returns
        -------
        int
        """
        return os.stat(self.filepath).st_size


class InputFile(object):
    """The InputFile represents the value for a template parameter of type
    'file'. This class extends the handle for an uploaded file with an optional
    target path that the user may have provided.
    """
    def __init__(self, f_handle, target_path=None):
        """Initialize the object properties.

        Parameters
        ----------
        f_handle: benchtmpl.io.files.base.FileHandle
        target_path: string, optional
        """
        self.f_handle = f_handle
        self.target_path = target_path

    @property
    def name(self):
        """Method for accessing the file name.

        Returns
        -------
        string
        """
        return self.f_handle.file_name

    def source(self):
        """Shortcut to get the source path for the file.

        Returns
        -------
        string
        """
        return self.f_handle.filepath

    def target(self):
        """Shortcut to get the target path for the file.

        Returns
        -------
        string
        """
        if not self.target_path is None:
            return self.target_path
        else:
            return self.f_handle.file_name
