import logging
from ConfigParser import SafeConfigParser

from boxv2 import BoxSession
import configargparse

from StubHubInventoryMechanizer.retry import retryloop


log = logging.getLogger(__name__)


class BoxHelper(object):
    '''
    classdocs
    '''

    def configure(self):
        p = configargparse.getArgumentParser()
        p.add_argument("--box_client_id", help="Box.com client-id")
        p.add_argument("--box_client_secret", help="Box.com client-secret")
        p.add_argument("--box_client_access_token", help="Box.com access token")
        p.add_argument("--box_client_refresh_token", help="Box.com refresh token")
        p.add_argument("--box_client_expire_timestamp", help="Box.com token expiration")
        p.add_argument("--box_auth_url", help="Box.com auth url")
        p.add_argument("--box_base_url", help="Box.com base url")
        return p.parse_known_args()[0]

    def __init__(self, client_id, client_secret, refresh_token, access_token, updatecallback):
        '''
        Constructor
        '''
        # handle config
        self.args = self.configure()
        if updatecallback is None:
            updatecallback = self.updateTokens

        self.session = BoxSession(client_id,
                                  client_secret,
                                  refresh_token,
                                  access_token,
                                  updatecallback)

        self.rootFolderId = self.getFolderId(self.args.root_folder, 0)
        self.clientFolderId = self.getFolderId(self.args.client_folder, self.rootFolderId)
        self.inputFolderId = self.getFolderId(self.args.input_folder, self.clientFolderId)
        self.logFolderId = self.getFolderId(self.args.log_folder, self.clientFolderId)
        self.outputFolderId = self.getFolderId(self.args.output_folder, self.clientFolderId)

    def getFolderId(self, folderName, parentId):
        try:
            for retry in retryloop(5, timeout=30):
                response = self.session.search(query=folderName,
                                               content_types='name',
                                               type='folder',
                                               ancestor_folder_ids=parentId)
                if response['total_count'] == 0:
                    retry()

            return response['entries'][0]['id']
        except:
            log.error('Exception - ', exc_info=1)
            return None

    def searchFolderContents(self, parentId):
        try:
            response = self.session.search(query='*SH*',
                                           content_types='name',
                                           type='file',
                                           file_extensions='csv',
                                           fields='name,created_at,modified_at',
                                           ancestor_folder_ids=parentId)
            log.debug('searchFolderContents = %s', response)
            return response['entries']
        except:
            log.error('Unhandled Exception', exc_info=1)
            return None

    def getFolderContents(self, parentId):
        try:
            response = self.session.get_folder_items(parentId)
            log.debug('getFolderContents = %s', response)
            return response['entries']

        except:
            log.error('Unhandled Exception', exc_info=True)

    def DownloadFiles(self, fileInfo, targetPath):
        for fi in fileInfo:
            log.info('Downloading input file %s', './{}/{}'.format(targetPath, fi['name']))
            self.session.download_file(fi['id'], './{}/{}'.format(targetPath, fi['name']))
            log.info('Downloaded input file %s', './{}/{}'.format(targetPath, fi['name']))

    def delete_files(self, filelist):
        for i in filelist:
            self.session.delete_file(i['id'])

    def upload_log_file(self, file_path, file_name):
        self.session.upload_file(file_name, self.logFolderId, file_path)

    def upload_output_file(self, file_path, file_name):
        existing = self.getFolderContents(self.outputFolderId)
        delete = []
        for i in existing:
            if i['name'] == file_name:
                delete.append(i)
        self.delete_files(delete)
        self.session.upload_file(file_name, self.outputFolderId, file_path)

    def updateTokens(self, refresh_token, access_token):
        filepath = './default.settings.config'
        parser = SafeConfigParser()
        parser.read(filepath)
        parser.set('SETTINGS', 'box_client_access_token', access_token)
        parser.set('SETTINGS', 'box_client_refresh_token', refresh_token)
        log.info('Updating Box Tokens access=%s refresh=%s', access_token, refresh_token)
        self.args.box_client_access_token = access_token
        self.args.box_client_refresh_token = refresh_token

        with open(filepath, 'wb') as configfile:
            parser.write(configfile)