# Path: muninn/storage/base.py
# class StorageBackend(object):
#     def __init__(self):
#         self.supports_symlinks = False
#         self.global_prefix = ''
# 
#     def get_tmp_root(self, product):
#         if self._tmp_root:
#             tmp_root = os.path.join(self._tmp_root, product.core.archive_path)
#             util.make_path(tmp_root)
#             return tmp_root
# 
#     def run_for_product(self, product, fn, use_enclosing_directory):
#         tmp_root = self.get_tmp_root(product)
#         product_path = self.product_path(product)
#         with util.TemporaryDirectory(dir=tmp_root, prefix=".run_for_product-",
#                                      suffix="-%s" % product.core.uuid.hex) as tmp_path:
#             self.get(product, product_path, tmp_path, use_enclosing_directory)
#             paths = [os.path.join(tmp_path, basename) for basename in os.listdir(tmp_path)]
#             return fn(paths)
# 
#     def prepare(self):
#         # Prepare storage for use.
#         raise NotImplementedError()
# 
#     def exists(self):
#         # Check that storage exists.
#         raise NotImplementedError()
# 
#     def initialize(self, configuration):
#         # Initialize storage.
#         raise NotImplementedError()
# 
#     def destroy(self):
#         # Destroy storage
#         raise NotImplementedError()
# 
#     def product_path(self, product):  # TODO refactor away?
#         # Product path within storage
#         raise NotImplementedError()
# 
#     # TODO lower-granularity put/get/delete
# 
#     def put(self, paths, properties, use_enclosing_directory, use_symlinks=None,
#             retrieve_files=None, run_for_product=None):
#         # Place product file(s) into storage
#         raise NotImplementedError()
# 
#     def get(self, product, product_path, target_path, use_enclosing_directory, use_symlinks=None):
#         # Retrieve product file(s) from storage
#         raise NotImplementedError()
# 
#     def size(self, product_path):
#         # Return product storage size
#         raise NotImplementedError()
# 
#     def delete(self, product_path, properties):
#         # Delete product file(s) from storage
#         raise NotImplementedError()
# 
#     def move(self, product, archive_path, paths=None):
#         # Move product
#         raise NotImplementedError()
# 
# Path: muninn/schema.py
# def prefix_message_with_path(path, message):
# def join(path, *args):
#     def __init__(self, type):
#     def __init__(self, optional=False, index=False):
#     def name(cls):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value, partial=False, path=""):
#     def __new__(meta, name, bases, dct):
#     def validate(cls, value, partial=False, path=""):
#     def __getitem__(cls, name):
#     def is_optional(cls, name):
#     def has_index(cls, name):
#     def __len__(cls):
#     def __iter__(cls):
#     def __contains__(cls, name):
# class optional(object):
# class Type(object):
# class Long(Type):
# class Integer(Type):
# class Real(Type):
# class Boolean(Type):
# class Text(Type):
# class Namespace(Type):
# class Timestamp(Type):
# class UUID(Type):
# class Geometry(Type):
# class Container(Type):
# class Sequence(Container):
# class MetaMapping(type):
# 
# Path: muninn/exceptions.py
# class Error(Exception):
#     pass
# 
# Path: muninn/util.py
# def product_size(roots, resolve_root=True, resolve_links=False):
#     def _product_size_rec(root, resolve_root, resolve_links):
#         if os.path.islink(root) and not (resolve_root or resolve_links):
#             # Use size of the symbolic link itself (instead of the size of its target).
#             return os.lstat(root).st_size
# 
#         elif os.path.isfile(root):
#             return os.stat(root).st_size
# 
#         elif os.path.isdir(root):
#             return sum([_product_size_rec(os.path.join(root, base), False, resolve_links) for base in os.listdir(root)])
# 
#         else:
#             raise IOError("path does not refer to a regular file or directory: %s" % root)
# 
#     if isinstance(roots, basestring):
#         roots = [roots]
# 
#     return sum([_product_size_rec(root, resolve_root, resolve_links) for root in roots])


import os
import muninn.util as util
import muninn.config as config
from .base import StorageBackend
from muninn.schema import Mapping, Text, Boolean
from muninn.exceptions import Error
from muninn.util import product_size




class _FSConfig(Mapping):
    _alias = "fs"

    root = Text()
    use_symlinks = Boolean(optional=True)


def create(configuration):
    fs_section = configuration.get("fs", {})
    if not fs_section:  # backward compatibility
        options = {}
        arch_section = configuration.get('archive')
        try:
            options['root'] = config.parse(arch_section['root'], Text)
        except KeyError:
            raise ValueError('archive: storage: fs: no value for mandatory item "root"')
        try:

# Path: muninn/storage/base.py
# class StorageBackend(object):
#     def __init__(self):
#         self.supports_symlinks = False
#         self.global_prefix = ''
# 
#     def get_tmp_root(self, product):
#         if self._tmp_root:
#             tmp_root = os.path.join(self._tmp_root, product.core.archive_path)
#             util.make_path(tmp_root)
#             return tmp_root
# 
#     def run_for_product(self, product, fn, use_enclosing_directory):
#         tmp_root = self.get_tmp_root(product)
#         product_path = self.product_path(product)
#         with util.TemporaryDirectory(dir=tmp_root, prefix=".run_for_product-",
#                                      suffix="-%s" % product.core.uuid.hex) as tmp_path:
#             self.get(product, product_path, tmp_path, use_enclosing_directory)
#             paths = [os.path.join(tmp_path, basename) for basename in os.listdir(tmp_path)]
#             return fn(paths)
# 
#     def prepare(self):
#         # Prepare storage for use.
#         raise NotImplementedError()
# 
#     def exists(self):
#         # Check that storage exists.
#         raise NotImplementedError()
# 
#     def initialize(self, configuration):
#         # Initialize storage.
#         raise NotImplementedError()
# 
#     def destroy(self):
#         # Destroy storage
#         raise NotImplementedError()
# 
#     def product_path(self, product):  # TODO refactor away?
#         # Product path within storage
#         raise NotImplementedError()
# 
#     # TODO lower-granularity put/get/delete
# 
#     def put(self, paths, properties, use_enclosing_directory, use_symlinks=None,
#             retrieve_files=None, run_for_product=None):
#         # Place product file(s) into storage
#         raise NotImplementedError()
# 
#     def get(self, product, product_path, target_path, use_enclosing_directory, use_symlinks=None):
#         # Retrieve product file(s) from storage
#         raise NotImplementedError()
# 
#     def size(self, product_path):
#         # Return product storage size
#         raise NotImplementedError()
# 
#     def delete(self, product_path, properties):
#         # Delete product file(s) from storage
#         raise NotImplementedError()
# 
#     def move(self, product, archive_path, paths=None):
#         # Move product
#         raise NotImplementedError()
# 
# Path: muninn/schema.py
# def prefix_message_with_path(path, message):
# def join(path, *args):
#     def __init__(self, type):
#     def __init__(self, optional=False, index=False):
#     def name(cls):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value):
#     def validate(cls, value, partial=False, path=""):
#     def __new__(meta, name, bases, dct):
#     def validate(cls, value, partial=False, path=""):
#     def __getitem__(cls, name):
#     def is_optional(cls, name):
#     def has_index(cls, name):
#     def __len__(cls):
#     def __iter__(cls):
#     def __contains__(cls, name):
# class optional(object):
# class Type(object):
# class Long(Type):
# class Integer(Type):
# class Real(Type):
# class Boolean(Type):
# class Text(Type):
# class Namespace(Type):
# class Timestamp(Type):
# class UUID(Type):
# class Geometry(Type):
# class Container(Type):
# class Sequence(Container):
# class MetaMapping(type):
# 
# Path: muninn/exceptions.py
# class Error(Exception):
#     pass
# 
# Path: muninn/util.py
# def product_size(roots, resolve_root=True, resolve_links=False):
#     def _product_size_rec(root, resolve_root, resolve_links):
#         if os.path.islink(root) and not (resolve_root or resolve_links):
#             # Use size of the symbolic link itself (instead of the size of its target).
#             return os.lstat(root).st_size
# 
#         elif os.path.isfile(root):
#             return os.stat(root).st_size
# 
#         elif os.path.isdir(root):
#             return sum([_product_size_rec(os.path.join(root, base), False, resolve_links) for base in os.listdir(root)])
# 
#         else:
#             raise IOError("path does not refer to a regular file or directory: %s" % root)
# 
#     if isinstance(roots, basestring):
#         roots = [roots]
# 
#     return sum([_product_size_rec(root, resolve_root, resolve_links) for root in roots])


# Path: muninn/storage/fs.py
import os
import muninn.util as util
import muninn.config as config
from .base import StorageBackend
from muninn.schema import Mapping, Text, Boolean
from muninn.exceptions import Error
from muninn.util import product_size





class _FSConfig(Mapping):
    _alias = "fs"

    root = Text()
    use_symlinks = Boolean(optional=True)


def create(configuration):
    fs_section = configuration.get("fs", {})
    if not fs_section:  # backward compatibility
        options = {}
        arch_section = configuration.get('archive')
        try:
            options['root'] = config.parse(arch_section['root'], Text)
        except KeyError:
            raise ValueError('archive: storage: fs: no value for mandatory item "root"')
        try:

            options['use_symlinks'] = config.parse(arch_section['use_symlinks'], Boolean)