#!/usr/bin/env python
# encoding: utf-8

# Copyright 2012 Aaron Morton
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#   http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
import cStringIO
import errno
import json
import logging
import os.path
import pkg_resources
import shutil
import time

import boto
from boto.s3 import key

from cassback import dt_util, file_util

# ============================================================================ 
#

def create_from_args(args):

    endpoint_name = args.endpoint
    for entry_point in pkg_resources.iter_entry_points("cassback.endpoints"):            
        
        endpoint_class = entry_point.load()
        if endpoint_class.name == endpoint_name:
            return endpoint_class(args)

    raise RuntimeError("Unknown endpoint name %s" % (endpoint_name,))

def validate_args(args):

    endpoint_name = args.endpoint
    for entry_point in pkg_resources.iter_entry_points("cassback.endpoints"):            
        
        endpoint_class = entry_point.load()
        if endpoint_class.name == endpoint_name:
            endpoint_class.validate_args(args)
            return

    raise RuntimeError("Unknown endpoint name %s" % (endpoint_name,))


# ============================================================================ 
#

class EndpointBase(object):
    """Base for all endpoints."""

    name = None
    """Endpoint name, used in command line to identifity it. 
    """

    @classmethod
    def add_arg_group(cls, main_parser):
        """
        """
        pass
    
    @classmethod
    def validate_args(cls, args):
        pass
        
    def backup_file(self, backup_file):
        """Store the SSTable ``backup_file``.
        
        Returns the fully qualified path to the file in the backup. 
        """
        raise NotImplementedError()

    def read_backup_file(self, path):
        """Creates a :cls:`cassandra.BackupFile` from the meta for the file 
        at ``path``
        """
        raise NotImplementedError()

    def backup_keyspace(self, ks_backup):
        raise NotImplementedError()

    def read_keyspace(self, path):
        raise NotImplementedError()

    def restore_file(self, backup_file, dest_prefix):
        """Restore the ``backup_file`` under the ``dest_prefix``.
        
        Returns the fully qualified backup path.
        """
        raise NotImplementedError()

    def exists(self, relative_path):
        """Returns ``True`` if the file at ``relative_path`` exists. False 
        otherwise. 
        """
        raise NotImplementedError()    

    def validate_checksum(self, relative_path, expected_md5_hex):
        """Validates that the MD5 checksum of the file in the backup at 
        ``relative_path`` matches ``expected_md5_hex``.  
        """
        raise NotImplementedError()


    def iter_dir(self, relative_path, include_files=True, 
        include_dirs=False, recursive=False):