import logging
import requests
import json
import re
from urllib.parse import urlparse

logging.basicConfig(format='%(asctime)-15s [%(name)s-%(process)d] %(levelname)s: %(message)s', level=logging.INFO)
__name__ = 'elastic_search'
logger = logging.getLogger(__name__)

class ElasticSearch:
    def __init__(self, domain, env, bucket_key):
        self.domain = domain
        self.env = env
        self.index = self.get_index(bucket_key)
        self.alias = self.get_alias(bucket_key)
        self.base_creation_url = "{}/{}/".format(self.domain, self.index)
        self.base_alias_url = "{}/{}/".format(self.domain, self.alias)
    #end __init__

    def create_index(self):
        if self.is_index_present():
            logger.info('index already exist, continue')
            return
        else:
            logger.info('create elastic_search index')
            try:
                headers = {'Content-Type' : 'application/json'}
                alias_payload = self.construct_alias_payload(self.alias)
                response = requests.put(self.base_creation_url, headers = headers, data = alias_payload)
                response.raise_for_status()
            except requests.exceptions.HTTPError as error:
                logger.info(error)
            except requests.exceptions.ConnectionError as error:
                logger.info(error)
            except requests.exceptions.Timeout as error:
                logger.info(error)
            except requests.exceptions.RequestException as error:
                logger.info(error)
    #end create_index

    def is_index_present(self):
        try:
            logger.info('is_index_present: ' + self.base_alias_url)
            response = requests.get(self.base_alias_url)
            response.raise_for_status()
            return True
        except:
            return False
    #end is_index_present

    # Insert a document in ElasticSearch
    # Exception Management : https://www.nylas.com/blog/use-python-requests-module-rest-apis/
    def put_item(self, bucket_key, raw_text, size, date_time):
        file_name = bucket_key.split('/')[-1]
        url = "{}_doc".format(self.base_alias_url)
        try:
            headers = {'Content-Type' : 'application/json'}
            query = {'id': bucket_key, 'refresh': 'true'}
            response = requests.post(url, headers = headers, data = json.dumps({'raw_text': raw_text, 'file_name': file_name, 'size': size, 'date': date_time}), params = query)
            response.raise_for_status()
        except requests.exceptions.HTTPError as error:
            logger.info(error)
        except requests.exceptions.ConnectionError as error:
            logger.info(error)
        except requests.exceptions.Timeout as error:
            logger.info(error)
        except requests.exceptions.RequestException as error:
            logger.info(error)
    #end put_item

    # Structure : {env}-{model_type}-{client bucket}-{userId}
    # example for my-documents/qa-client-softsell/1234/A_File.pdf in QA
    # the generated index will be : qa-my-documents-qa-client-softsell-1234
    # TODO Enterprise Library (PA-320)
    def get_index(self, bucket_key):
        if re.search('my-documents/([\w-]+)/(\d+)/', bucket_key):
            paths = bucket_key.split('/')
            clientBucket = paths[1]
            userId = paths[2]
            if self.env == 'prod':
                return '{}-{}-{}'.format('my-documents', clientBucket, userId)
            else:
                return '{}-{}-{}-{}'.format(self.env, 'my-documents', clientBucket, userId)
        elif re.search('library/draft/', bucket_key):
            # TODO Enterprise Library (PA-320)
            return ''
        else:
            return ''
    #end get_index

    # Structure : {env}-{client bucket}-{userId}-{model-type}
    # example for my-documents/qa-client-softsell/1234/A_File.pdf in QA
    # the generated alias will be : qa-qa-client-softsell-1234-my-documents
    def get_alias(self, bucket_key):
        if re.search('my-documents/([\w-]+)/(\d+)/', bucket_key):
            paths = bucket_key.split('/')
            clientBucket = paths[1]
            userId = paths[2]
            if self.env == 'prod':
                return '{}-{}-{}'.format(clientBucket, userId, 'my-documents')
            else:
                return '{}-{}-{}-{}'.format(self.env, clientBucket, userId, 'my-documents')
        elif re.search('library/draft/', bucket_key):
            # TODO Enterprise Library (PA-320)
            return ''
        else:
            return ''
    #end get_alias

    def construct_alias_payload(self, alias):
        return json.dumps({'aliases': {alias: {}}})
   #end construct_alias_payload

#end ElasticSearch