import json
import requests
import datetime
import time
import sys
import re
import plotly.plotly as py
import plotly.graph_objs as graph

from time import mktime
from datetime import date
from pprint import pprint
from bug_backlog import Backlog
from bug_components import Component
from bug_developers import Assignee

REST = '/rest'

DATE_REGEX='^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$'
DATE_PATTERN = re.compile(DATE_REGEX)

INCLUDE_FIELDS = '&include_fields=id,component,classification,creation_time,last_change_time,is_open,priority,severity,status,summary,assigned_to,resolution'

BUG_STATUS_FIELD_NAME = 'bug_status'

BUG_RESOLUTION_FIELD_NAME = 'resolution'

BACKLOG_CALLBACK = 'backlog_callback'

ASSIGNEES_STATUS_CALLBACK = 'assignee_status_callback'

ASSIGNEES_RESOLUTION_CALLBACK = 'assignee_resolution_callback'

DETAILS_CALLBACK = 'assignees_details_callback'

COMPONENTS_CALLBACK = 'component_callback'

STATUS_CALLBACK = 'status_callback'

RESOLUTION_CALLBACK = 'resolutions_callback'

class DataJSONEncoder(json.JSONEncoder):

  def default(self, obj):
    if isinstance(obj, datetime.datetime):
      return obj.isoformat()
    elif isinstance(obj, datetime.date):
      return obj.isoformat()
    elif isinstance(obj, datetime.timedelta):
      return (datetime.datetime.min + obj).time().isoformat()
    elif isinstance(obj, set):
        return list(obj)

    return json.JSONEncoder.default(self, obj)

class Bugzilla:
  """
    Bugzilla data extract API.
    Get data from a bugzilla 5.0 server through its REST API
  """

  def __init__(self, username, password, uri):
    """
      Constructor with a username, password and uri of the bugzilla server
      After the BugzillaReport has been initialized, it will have a dictionary data-structure
      containing lists for all the opened, closed, assigned, and so forth bugs.
      According to called methods, this dictionary is filled
    """
    self.username = username
    self.password = password
    self.uri = uri + REST
    self.loggedIn = False
    self.loginInfo = None
    self.from_date = None
    self.status = []
    self.resolutions = []
    self.bugs = {'all' : []}

  def isLoggedIn(self):
    """ Verify if the user is logged in """
    if not self.loggedIn:
      raise RuntimeError('Sorry. You are not logged in.')

  def getTokenParam(self):
    """ Add the token parameter to the request uri """
    return 'token=' +self.loginInfo['token']

  def getRequest(self, uri):
    # Set verify = False to disable SSL verification
    data = requests.get(uri, verify=True)
    return data

  def setUp(self):
    """
      Set up the initial data required in order to create the report
      Such set up includes logging in and extracting configurable bug statuses and resolutions
    """
    self.login()

    data = self.getField(BUG_STATUS_FIELD_NAME)
    self.setBugStatus(data)

    data = self.getField(BUG_RESOLUTION_FIELD_NAME)
    self.setBugResolutions(data)