"""PredictionIO Python SDK
The PredictionIO Python SDK provides easy-to-use functions for integrating
Python applications with PredictionIO REST API services.
"""


__version__ = "0.9.8"

# import packages
import re
try:
  import httplib
except ImportError:
  # pylint: disable=F0401
  # http is a Python3 module, replacing httplib
  from http import client as httplib

try:
  from urllib import urlencode
except ImportError:
  # pylint: disable=F0401,E0611
  from urllib.parse import urlencode

import json
import urllib

from datetime import datetime
import pytz

from predictionio.connection import Connection
from predictionio.connection import AsyncRequest
from predictionio.connection import AsyncResponse
from predictionio.connection import PredictionIOAPIError


class NotCreatedError(PredictionIOAPIError):
  pass


class NotFoundError(PredictionIOAPIError):
  pass


def event_time_validation(t):
  """ Validate event_time according to EventAPI Specification.
  """

  if t is None:
    return datetime.now(pytz.utc)

  if type(t) != datetime:
    raise AttributeError("event_time must be datetime.datetime")

  if t.tzinfo is None:
    raise AttributeError("event_time must have tzinfo")

  return t


class BaseClient(object):
  def __init__(self, url, threads=1, qsize=0, timeout=5):
    """Constructor of Client object.
    """
    self.threads = threads
    self.url = url
    self.qsize = qsize
    self.timeout = timeout

    # check connection type
    https_pattern = r'^https://(.*)'
    http_pattern = r'^http://(.*)'
    m = re.match(https_pattern, url)
    self.https = True
    if m is None:  # not matching https
      m = re.match(http_pattern, url)
      self.https = False
      if m is None:  # not matching http either
        raise InvalidArgumentError("url is not valid: %s" % url)
    self.host = m.group(1)

    self._uid = None  # identified uid
    self._connection = Connection(host=self.host, threads=self.threads,
                    qsize=self.qsize, https=self.https,
                    timeout=self.timeout)

  def close(self):
    """Close this client and the connection.
    Call this method when you want to completely terminate the connection
    with PredictionIO.
    It will wait for all pending requests to finish.
    """
    self._connection.close()

  def pending_requests(self):
    """Return the number of pending requests.
    :returns:
      The number of pending requests of this client.
    """
    return self._connection.pending_requests()

  def get_status(self):
    """Get the status of the PredictionIO API Server
    :returns:
      status message.
    :raises:
      ServerStatusError.
    """
    path = "/"
    request = AsyncRequest("GET", path)
    request.set_rfunc(self._aget_resp)
    self._connection.make_request(request)
    result = request.get_response()
    return result

  def _acreate_resp(self, response):
    if response.error is not None:
      raise NotCreatedError("Exception happened: %s for request %s" %
                    (response.error, response.request))
    elif response.status != httplib.CREATED:
      raise NotCreatedError("request: %s status: %s body: %s" %
                    (response.request, response.status,
                     response.body))

    return response

  def _aget_resp(self, response):
    if response.error is not None:
      raise NotFoundError("Exception happened: %s for request %s" %
                  (response.error, response.request))
    elif response.status != httplib.OK:
      raise NotFoundError("request: %s status: %s body: %s" %
                  (response.request, response.status,
                   response.body))

    return response.json_body

  def _adelete_resp(self, response):
    if response.error is not None:
      raise NotFoundError("Exception happened: %s for request %s" %
                  (response.error, response.request))
    elif response.status != httplib.OK:
      raise NotFoundError("request: %s status: %s body: %s" %
                  (response.request, response.status,
                   response.body))

    return response.body


class EventClient(BaseClient):
  """Client for importing data into PredictionIO Event Server.
  Notice that app_id has been deprecated as of 0.8.2. Please use access_token
  instead.
  :param access_key: the access key for your application.
  :param url: the url of PredictionIO Event Server.
  :param threads: number of threads to handle PredictionIO API requests.
          Must be >= 1.
  :param qsize: the max size of the request queue (optional).
      The asynchronous request becomes blocking once this size has been
      reached, until the queued requests are handled.
      Default value is 0, which means infinite queue size.
  :param timeout: timeout for HTTP connection attempts and requests in
    seconds (optional).
    Default value is 5.
  :param channel: channel name (optional)
  """

  def __init__(self, access_key,
      url="http://localhost:7070",
      threads=1, qsize=0, timeout=5, channel=None):
    assert type(access_key) is str, ("access_key must be string. "
        "Notice that app_id has been deprecated in Prediction.IO 0.8.2. "
        "Please use access_key instead.")

    super(EventClient, self).__init__(url, threads, qsize, timeout)

    if len(access_key) <= 8:
      raise DeprecationWarning(
          "It seems like you are specifying an app_id. It is deprecated in "
          "Prediction.IO 0.8.2. Please use access_key instead. Or, "
          "you may use an earlier version of this sdk.")

    self.access_key = access_key
    self.channel = channel

  def acreate_event(self, event, entity_type, entity_id,
      target_entity_type=None, target_entity_id=None, properties=None,
      event_time=None):
    """Asynchronously create an event.
    :param event: event name. type str.
    :param entity_type: entity type. It is the namespace of the entityId and
      analogous to the table name of a relational database. The entityId must be
      unique within same entityType. type str.
    :param entity_id: entity id. *entity_type-entity_id* becomes the unique
      identifier of the entity. For example, you may have entityType named user,
      and different entity IDs, say 1 and 2. In this case, user-1 and user-2
      uniquely identifies entities. type str
    :param target_entity_type: target entity type. type str.
    :param target_entity_id: target entity id. type str.
    :param properties: a custom dict associated with an event. type dict.
    :param event_time: the time of the event. type datetime, must contain
      timezone info.
    :returns:
      AsyncRequest object. You can call the get_response() method using this
      object to get the final resuls or status of this asynchronous request.
    """
    data = {
        "event": event,
        "entityType": entity_type,
        "entityId": entity_id,
        }

    if target_entity_type is not None:
      data["targetEntityType"] = target_entity_type

    if target_entity_id is not None:
      data["targetEntityId"] = target_entity_id

    if properties is not None:
      data["properties"] = properties

    et = event_time_validation(event_time)
    # EventServer uses milliseconds, but python datetime class uses micro. Hence
    # need to skip the last three digits.
    et_str = et.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + et.strftime("%z")
    data["eventTime"] = et_str

    qparam = {
        "accessKey" : self.access_key
        }

    if self.channel is not None:
      qparam["channel"] = self.channel

    path = "/events.json?%s" % (urlencode(qparam), )

    request = AsyncRequest("POST", path, **data)
    request.set_rfunc(self._acreate_resp)
    self._connection.make_request(request)
    return request

  def create_event(self, event, entity_type, entity_id,
      target_entity_type=None, target_entity_id=None, properties=None,
      event_time=None):
    """Synchronously (blocking) create an event."""
    return self.acreate_event(event, entity_type, entity_id,
        target_entity_type, target_entity_id, properties,
        event_time).get_response()

  def aget_event(self, event_id):
    """Asynchronouly get an event from Event Server.
    :param event_id: event id returned by the EventServer when creating the
      event.
    :returns:
      AsyncRequest object.
    """
    qparam = {
        "accessKey" : self.access_key
        }

    if self.channel is not None:
      qparam["channel"] = self.channel

    enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
    path = "/events/%s.json" % (enc_event_id, )
    request = AsyncRequest("GET", path, **qparam)
    request.set_rfunc(self._aget_resp)
    self._connection.make_request(request)
    return request

  def get_event(self, event_id):
    """Synchronouly get an event from Event Server."""
    return self.aget_event(event_id).get_response()

  def aget_events(self, startTime=None, untilTime=None, entityType=None, entityId=None, limit=None, reversed=False):
    """Asynchronouly get events from Event Server. (Getting events through the Event Server API is used for debugging and not recommended for production)
    :param startTime: time in ISO8601 format. Return events with eventTime >= startTime.
    :param untilTime: time in ISO8601 format. Return events with eventTime < untilTime.
    :param entityId: String. The entityId. Return events for this entityId only.
    :param limit: Integer. The number of record events returned. Default is 20. -1 to get all.
    :param reversed: Boolean. Must be used with both entityType and entityId specified,
      returns events in reversed chronological order. Default is false.
    :returns:
      AsyncRequest object.
    """
    qparam = {
        "accessKey" : self.access_key,
        "reversed": reversed
      }

    if startTime is not None:
      qparam["startTime"] = startTime

    if untilTime is not None:
      qparam["untilTime"] = untilTime

    if entityType is not None:
      qparam["entityType"] = entityType

    if entityId is not None:
      qparam["entityId"] = entityId

    if limit is not None:
      qparam["limit"] = limit

    if self.channel is not None:
      qparam["channel"] = self.channel
    path = "/events.json"
    request = AsyncRequest("GET", path, **qparam)
    request.set_rfunc(self._aget_resp)
    self._connection.make_request(request)
    return request

  def get_events(self, startTime=None, untilTime=None, entityType=None, entityId=None, limit=None, reversed=False):
    """Synchronouly get event from Event Server. (Getting events through the Event Server API is used for debugging and not recommended for production)"""
    return self.aget_events(
      startTime=startTime,
      untilTime=untilTime,
      entityType=entityType,
      entityId=entityId,
      limit=limit,
      reversed=reversed
    ).get_response()

  def adelete_event(self, event_id):
    """Asynchronouly delete an event from Event Server.
    :param event_id: event id returned by the EventServer when creating the
      event.
    :returns:
      AsyncRequest object.
    """
    qparam = {
        "accessKey" : self.access_key
        }

    if self.channel is not None:
      qparam["channel"] = self.channel

    enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
    path = "/events/%s.json" % (enc_event_id, )
    request = AsyncRequest("DELETE", path, **qparam)
    request.set_rfunc(self._adelete_resp)
    self._connection.make_request(request)
    return request

  def delete_event(self, event_id):
    """Synchronouly delete an event from Event Server."""
    return self.adelete_event(event_id).get_response()

  ## Below are helper functions

  def aset_user(self, uid, properties={}, event_time=None):
    """Set properties of a user.
    Wrapper of acreate_event function, setting event to "$set" and entity_type
    to "user".
    """
    return self.acreate_event(
      event="$set",
      entity_type="user",
      entity_id=uid,
      properties=properties,
      event_time=event_time,
    )

  def set_user(self, uid, properties={}, event_time=None):
    """Set properties of a user"""
    return self.aset_user(uid, properties, event_time).get_response()

  def aunset_user(self, uid, properties, event_time=None):
    """Unset properties of an user.
    Wrapper of acreate_event function, setting event to "$unset" and entity_type
    to "user".
    """
    # check properties={}, it cannot be empty
    return self.acreate_event(
        event="$unset",
        entity_type="user",
        entity_id=uid,
        properties=properties,
        event_time=event_time,
        )

  def unset_user(self, uid, properties, event_time=None):
    """Set properties of a user"""
    return self.aunset_user(uid, properties, event_time).get_response()

  def adelete_user(self, uid, event_time=None):
    """Delete a user.
    Wrapper of acreate_event function, setting event to "$delete" and entity_type
    to "user".
    """
    return self.acreate_event(
        event="$delete",
        entity_type="user",
        entity_id=uid,
        event_time=event_time)

  def delete_user(self, uid, event_time=None):
    """Delete a user."""
    return self.adelete_user(uid, event_time).get_response()

  def aset_item(self, iid, properties={}, event_time=None):
    """Set properties of an item.
    Wrapper of acreate_event function, setting event to "$set" and entity_type
    to "item".
    """
    return self.acreate_event(
        event="$set",
        entity_type="item",
        entity_id=iid,
        properties=properties,
        event_time=event_time)

  def set_item(self, iid, properties={}, event_time=None):
    """Set properties of an item."""
    return self.aset_item(iid, properties, event_time).get_response()

  def aunset_item(self, iid, properties={}, event_time=None):
    """Unset properties of an item.
    Wrapper of acreate_event function, setting event to "$unset" and entity_type
    to "item".
    """
    return self.acreate_event(
        event="$unset",
        entity_type="item",
        entity_id=iid,
        properties=properties,
        event_time=event_time)

  def unset_item(self, iid, properties={}, event_time=None):
    """Unset properties of an item."""
    return self.aunset_item(iid, properties, event_time).get_response()

  def adelete_item(self, iid, event_time=None):
    """Delete an item.
    Wrapper of acreate_event function, setting event to "$delete" and entity_type
    to "item".
    """
    return self.acreate_event(
        event="$delete",
        entity_type="item",
        entity_id=iid,
        event_time=event_time)

  def delete_item(self, iid, event_time=None):
    """Delete an item."""
    return self.adelete_item(iid, event_time).get_response()

  def arecord_user_action_on_item(self, action, uid, iid, properties={},
      event_time=None):
    """Create a user-to-item action.
    Wrapper of acreate_event function, setting entity_type to "user" and
    target_entity_type to "item".
    """
    return self.acreate_event(
        event=action,
        entity_type="user",
        entity_id=uid,
        target_entity_type="item",
        target_entity_id=iid,
        properties=properties,
        event_time=event_time)

  def record_user_action_on_item(self, action, uid, iid, properties={},
      event_time=None):
    """Create a user-to-item action."""
    return self.arecord_user_action_on_item(
      action, uid, iid, properties, event_time).get_response()


class EngineClient(BaseClient):
  """Client for extracting prediction results from an PredictionIO Engine
  Instance.
  :param url: the url of the PredictionIO Engine Instance.
  :param threads: number of threads to handle PredictionIO API requests.
          Must be >= 1.
  :param qsize: the max size of the request queue (optional).
      The asynchronous request becomes blocking once this size has been
      reached, until the queued requests are handled.
      Default value is 0, which means infinite queue size.
  :param timeout: timeout for HTTP connection attempts and requests in
    seconds (optional).
    Default value is 5.
  """
  def __init__(self, url="http://localhost:8000", threads=1,
      qsize=0, timeout=5):
    super(EngineClient, self).__init__(url, threads, qsize, timeout)

  def asend_query(self, data):
    """Asynchronously send a request to the engine instance with data as the
    query.
    :param data: the query: It is coverted to an json object using json.dumps
      method. type dict.
    :returns:
      AsyncRequest object. You can call the get_response() method using this
      object to get the final resuls or status of this asynchronous request.
    """
    path = "/queries.json"
    request = AsyncRequest("POST", path, **data)
    request.set_rfunc(self._aget_resp)
    self._connection.make_request(request)
    return request

  def send_query(self, data):
    """Synchronously send a request.
    :param data: the query: It is coverted to an json object using json.dumps
      method. type dict.
    :returns: the prediction.
    """
    return self.asend_query(data).get_response()

class FileExporter(object):
  """File exporter to write events to JSON file for batch import
  :param file_name: the destination file name
  """
  def __init__(self, file_name):
    """Constructor of Exporter.
    """
    self._file = open(file_name, 'w')

  def create_event(self, event, entity_type, entity_id,
      target_entity_type=None, target_entity_id=None, properties=None,
      event_time=None):
    """Create an event and write to the file.
    (please refer to EventClient's create_event())
    """
    data = {
        "event": event,
        "entityType": entity_type,
        "entityId": entity_id,
        }

    if target_entity_type is not None:
      data["targetEntityType"] = target_entity_type

    if target_entity_id is not None:
      data["targetEntityId"] = target_entity_id

    if properties is not None:
      data["properties"] = properties

    et = event_time_validation(event_time)
    # EventServer uses milliseconds, but python datetime class uses micro. Hence
    # need to skip the last three digits.
    et_str = et.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + et.strftime("%z")
    data["eventTime"] = et_str

    j = json.dumps(data)
    self._file.write(j+"\n")

  def close(self):
    """Close the FileExporter
    Call this method when you finish writing all events to JSON file
    """
    self._file.close()
