# 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
# 
# class StorageError(Error):
#     def __init__(self, orig, anything_stored):
#         self.orig = orig
#         self.anything_stored = anything_stored


import json
import logging
import os
import muninn.config as config
import muninn.util as util
import boto3
import boto3.s3
import botocore
from .base import StorageBackend
from muninn.schema import Mapping, Text, Integer
from muninn.exceptions import Error, StorageError




logging.getLogger("boto3").setLevel(logging.CRITICAL)


class _S3Config(Mapping):
    _alias = "s3"

    host = Text()
    port = Integer()
    bucket = Text()
    access_key = Text()
    secret_access_key = Text()
    region = Text(optional=True)
    prefix = Text(optional=True)
    tmp_root = Text(optional=True)
    download_args = Text(optional=True)  # JSON representation of boto3 download_file ExtraArgs parameter
    upload_args = Text(optional=True)  # JSON representation of boto3 upload_file ExtraArgs parameter
    copy_args = Text(optional=True)  # JSON representation of boto3 copy ExtraArgs parameter

# 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
# 
# class StorageError(Error):
#     def __init__(self, orig, anything_stored):
#         self.orig = orig
#         self.anything_stored = anything_stored


# Path: muninn/storage/s3.py
import json
import logging
import os
import muninn.config as config
import muninn.util as util
import boto3
import boto3.s3
import botocore
from .base import StorageBackend
from muninn.schema import Mapping, Text, Integer
from muninn.exceptions import Error, StorageError





logging.getLogger("boto3").setLevel(logging.CRITICAL)


class _S3Config(Mapping):
    _alias = "s3"

    host = Text()
    port = Integer()
    bucket = Text()
    access_key = Text()
    secret_access_key = Text()
    region = Text(optional=True)
    prefix = Text(optional=True)
    tmp_root = Text(optional=True)
    download_args = Text(optional=True)  # JSON representation of boto3 download_file ExtraArgs parameter
    upload_args = Text(optional=True)  # JSON representation of boto3 upload_file ExtraArgs parameter
    copy_args = Text(optional=True)  # JSON representation of boto3 copy ExtraArgs parameter

    transfer_config = Text(optional=True)  # JSON representation of boto3.s3.transfer.TransferConfig parameters