# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""The TemplateService class providing methods for template persistence."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import collections
import logging

import settings

from framework import exceptions
from framework import sql
from mrproto import tracker_pb2
from services import caches
from services import project_svc
from tracker import tracker_bizobj
from tracker import tracker_constants


TEMPLATE_COLS = [
    'id', 'project_id', 'name', 'content', 'summary', 'summary_must_be_edited',
    'owner_id', 'status', 'members_only', 'owner_defaults_to_member',
    'component_required']
TEMPLATE2LABEL_COLS = ['template_id', 'label']
TEMPLATE2COMPONENT_COLS = ['template_id', 'component_id']
TEMPLATE2ADMIN_COLS = ['template_id', 'admin_id']
TEMPLATE2FIELDVALUE_COLS = [
    'template_id', 'field_id', 'int_value', 'str_value', 'user_id',
    'date_value', 'url_value']
ISSUEPHASEDEF_COLS = ['id', 'name', 'rank']
TEMPLATE2APPROVALVALUE_COLS = [
    'approval_id', 'template_id', 'phase_id', 'status']


TEMPLATE_TABLE_NAME = 'Template'
TEMPLATE2LABEL_TABLE_NAME = 'Template2Label'
TEMPLATE2ADMIN_TABLE_NAME = 'Template2Admin'
TEMPLATE2COMPONENT_TABLE_NAME = 'Template2Component'
TEMPLATE2FIELDVALUE_TABLE_NAME = 'Template2FieldValue'
ISSUEPHASEDEF_TABLE_NAME = 'IssuePhaseDef'
TEMPLATE2APPROVALVALUE_TABLE_NAME = 'Template2ApprovalValue'


class TemplateSetTwoLevelCache(caches.AbstractTwoLevelCache):
  """Class to manage RAM and memcache for templates.

  Holds a dictionary of {project_id: templateset} key value pairs,
  where a templateset is a list of all templates in a project.
  """

  def __init__(self, cache_manager, template_service):
    super(TemplateSetTwoLevelCache, self).__init__(
        cache_manager, 'project', prefix='templateset:', pb_class=None)
    self.template_service = template_service

  def _MakeCache(self, cache_manager, kind, max_size=None):
    """Make the RAM cache and register it with the cache_manager."""
    return caches.RamCache(cache_manager, kind, max_size=max_size)

  def FetchItems(self, cnxn, keys):
    """On RAM and memcache miss, hit the database."""
    template_set_dict = {}

    for project_id in keys:
      template_set_dict.setdefault(project_id, [])
      template_rows = self.template_service.template_tbl.Select(
          cnxn, cols=TEMPLATE_COLS, project_id=project_id,
          order_by=[('name', [])])
      for (template_id, _project_id, template_name, _content, _summary,
           _summary_must_be_edited, _owner_id, _status, members_only,
           _owner_defaults_to_member, _component_required) in template_rows:
        template_set_row = (template_id, template_name, members_only)
        template_set_dict[project_id].append(template_set_row)

    return template_set_dict


class TemplateDefTwoLevelCache(caches.AbstractTwoLevelCache):
  """Class to manage RAM and memcache for individual TemplateDef.

  Holds a dictionary of {template_id: TemplateDef} key value pairs.
  """
  def __init__(self, cache_manager, template_service):
    super(TemplateDefTwoLevelCache, self).__init__(
        cache_manager,
        'template',
        prefix='templatedef:',
        pb_class=tracker_pb2.TemplateDef)
    self.template_service = template_service

  def _MakeCache(self, cache_manager, kind, max_size=None):
    """Make the RAM cache and register it with the cache_manager."""
    return caches.RamCache(cache_manager, kind, max_size=max_size)

  def FetchItems(self, cnxn, keys):
    """On RAM and memcache miss, hit the database.

    Args:
      cnxn: A MonorailConnection.
      keys: A list of template IDs (ints).

    Returns:
      A dict of {template_id: TemplateDef}.
    """
    template_dict = {}

    # Fetch template rows and relations.
    template_rows = self.template_service.template_tbl.Select(
        cnxn, cols=TEMPLATE_COLS, id=keys,
        order_by=[('name', [])])

    template2label_rows = self.template_service.\
        template2label_tbl.Select(
            cnxn, cols=TEMPLATE2LABEL_COLS, template_id=keys)
    template2component_rows = self.template_service.\
        template2component_tbl.Select(
            cnxn, cols=TEMPLATE2COMPONENT_COLS, template_id=keys)
    template2admin_rows = self.template_service.template2admin_tbl.Select(
        cnxn, cols=TEMPLATE2ADMIN_COLS, template_id=keys)
    template2fieldvalue_rows = self.template_service.\
        template2fieldvalue_tbl.Select(
            cnxn, cols=TEMPLATE2FIELDVALUE_COLS, template_id=keys)
    template2approvalvalue_rows = self.template_service.\
        template2approvalvalue_tbl.Select(
            cnxn, cols=TEMPLATE2APPROVALVALUE_COLS, template_id=keys)
    phase_ids = [av_row[2] for av_row in template2approvalvalue_rows]
    phase_rows = []
    if phase_ids:
      phase_rows = self.template_service.issuephasedef_tbl.Select(
          cnxn, cols=ISSUEPHASEDEF_COLS, id=list(set(phase_ids)))

    # Build TemplateDef with all related data.
    for template_row in template_rows:
      template = UnpackTemplate(template_row)
      template_dict[template.template_id] = template

    for template2label_row in template2label_rows:
      template_id, label = template2label_row
      template = template_dict.get(template_id)
      if template:
        template.labels.append(label)

    for template2component_row in template2component_rows:
      template_id, component_id = template2component_row
      template = template_dict.get(template_id)
      if template:
        template.component_ids.append(component_id)

    for template2admin_row in template2admin_rows:
      template_id, admin_id = template2admin_row
      template = template_dict.get(template_id)
      if template:
        template.admin_ids.append(admin_id)

    for fv_row in template2fieldvalue_rows:
      (template_id, field_id, int_value, str_value, user_id,
       date_value, url_value) = fv_row
      fv = tracker_bizobj.MakeFieldValue(
          field_id, int_value, str_value, user_id, date_value, url_value,
          False)
      template = template_dict.get(template_id)
      if template:
        template.field_values.append(fv)

    phases_by_id = {}
    for phase_row in phase_rows:
      (phase_id, name, rank) = phase_row
      phase = tracker_pb2.Phase(
          phase_id=phase_id, name=name, rank=rank)
      phases_by_id[phase_id] = phase

    # Note: there is no templateapproval2approver_tbl.
    for av_row in template2approvalvalue_rows:
      (approval_id, template_id, phase_id, status) = av_row
      approval_value = tracker_pb2.ApprovalValue(
          approval_id=approval_id, phase_id=phase_id,
          status=tracker_pb2.ApprovalStatus(status.upper()))
      template = template_dict.get(template_id)
      if template:
        template.approval_values.append(approval_value)
        phase = phases_by_id.get(phase_id)
        if phase and phase not in template.phases:
          template_dict.get(template_id).phases.append(phase)

    return template_dict


class TemplateService(object):

  def __init__(self, cache_manager):
    self.template_tbl = sql.SQLTableManager(TEMPLATE_TABLE_NAME)
    self.template2label_tbl = sql.SQLTableManager(TEMPLATE2LABEL_TABLE_NAME)
    self.template2component_tbl = sql.SQLTableManager(
        TEMPLATE2COMPONENT_TABLE_NAME)
    self.template2admin_tbl = sql.SQLTableManager(TEMPLATE2ADMIN_TABLE_NAME)
    self.template2fieldvalue_tbl = sql.SQLTableManager(
        TEMPLATE2FIELDVALUE_TABLE_NAME)
    self.issuephasedef_tbl = sql.SQLTableManager(
        ISSUEPHASEDEF_TABLE_NAME)
    self.template2approvalvalue_tbl = sql.SQLTableManager(
        TEMPLATE2APPROVALVALUE_TABLE_NAME)

    self.template_set_2lc = TemplateSetTwoLevelCache(cache_manager, self)
    self.template_def_2lc = TemplateDefTwoLevelCache(cache_manager, self)

  def CreateDefaultProjectTemplates(self, cnxn, project_id):
    """Create the default templates for a project.

    Used only when creating a new project.

    Args:
      cnxn: A MonorailConnection instance.
      project_id: The project ID under which to create the templates.
    """
    for tpl in tracker_constants.DEFAULT_TEMPLATES:
      tpl = tracker_bizobj.ConvertDictToTemplate(tpl)
      self.CreateIssueTemplateDef(cnxn, project_id, tpl.name, tpl.content,
          tpl.summary, tpl.summary_must_be_edited, tpl.status, tpl.members_only,
          tpl.owner_defaults_to_member, tpl.component_required, tpl.owner_id,
          tpl.labels, tpl.component_ids, tpl.admin_ids, tpl.field_values,
          tpl.phases)

  def GetTemplateByName(self, cnxn, template_name, project_id):
    """Retrieves a template by name and project_id.

    Args:
      template_name (string): name of template.
      project_id (int): ID of project template is under.

    Returns:
      A Template PB if found, otherwise None.
    """
    template_set = self.GetTemplateSetForProject(cnxn, project_id)
    for tpl_id, name, _members_only in template_set:
      if template_name == name:
        return self.GetTemplateById(cnxn, tpl_id)

  def GetTemplateById(self, cnxn, template_id):
    """Retrieves one template.

    Args:
      template_id (int): ID of the template.

    Returns:
      A TemplateDef PB if found, otherwise None.
    """
    result_dict, _ = self.template_def_2lc.GetAll(cnxn, [template_id])
    try:
      return result_dict[template_id]
    except KeyError:
      return None

  def GetTemplatesById(self, cnxn, template_ids):
    """Retrieves one or more templates by ID.

    Args:
      template_id (list<int>): IDs of the templates.

    Returns:
      A list containing any found TemplateDef PBs.
    """
    result_dict, _ = self.template_def_2lc.GetAll(cnxn, template_ids)
    return list(result_dict.values())

  def GetTemplateSetForProject(self, cnxn, project_id):
    """Get the TemplateSet for a project."""
    result_dict, _ = self.template_set_2lc.GetAll(cnxn, [project_id])
    return result_dict[project_id]

  def GetProjectTemplates(self, cnxn, project_id):
    """Gets all templates in a given project.

    Args:
      cnxn: A MonorailConnection instance.
      project_id: All templates for this project will be returned.

    Returns:
      A list of TemplateDefs.
    """
    template_set = self.GetTemplateSetForProject(cnxn, project_id)
    template_ids = [row[0] for row in template_set]
    return self.GetTemplatesById(cnxn, template_ids)

  def TemplatesWithComponent(self, cnxn, component_id):
    """Returns all templates with the specified component.

    Args:
      cnxn: connection to SQL database.
      component_id: int component id.

    Returns:
      A list of TemplateDefs.
    """
    template2component_rows = self.template2component_tbl.Select(
        cnxn, cols=['template_id'], component_id=component_id)
    template_ids = [r[0] for r in template2component_rows]
    return self.GetTemplatesById(cnxn, template_ids)

  def CreateIssueTemplateDef(
      self, cnxn, project_id, name, content, summary, summary_must_be_edited,
      status, members_only, owner_defaults_to_member, component_required,
      owner_id=None, labels=None, component_ids=None, admin_ids=None,
      field_values=None, phases=None, approval_values=None):
    """Create a new issue template definition with the given info.

    Args:
      cnxn: connection to SQL database.
      project_id: int ID of the current project.
      name: name of the new issue template.
      content: string content of the issue template.
      summary: string summary of the issue template.
      summary_must_be_edited: True if the summary must be edited when this
          issue template is used to make a new issue.
      status: string default status of a new issue created with this template.
      members_only: True if only members can view this issue template.
      owner_defaults_to_member: True is issue owner should be set to member
          creating the issue.
      component_required: True if a component is required.
      owner_id: user_id of default owner, if any.
      labels: list of string labels for the new issue, if any.
      component_ids: list of component_ids, if any.
      admin_ids: list of admin_ids, if any.
      field_values: list of FieldValue PBs, if any.
      phases: list of Phase PBs, if any.
      approval_values: list of ApprovalValue PBs, if any.

    Returns:
      Integer template_id of the new issue template definition.
    """
    template_id = self.template_tbl.InsertRow(
        cnxn, project_id=project_id, name=name, content=content,
        summary=summary, summary_must_be_edited=summary_must_be_edited,
        owner_id=owner_id, status=status, members_only=members_only,
        owner_defaults_to_member=owner_defaults_to_member,
        component_required=component_required, commit=False)

    if labels:
      self.template2label_tbl.InsertRows(
          cnxn, TEMPLATE2LABEL_COLS, [(template_id, label) for label in labels],
          commit=False)
    if component_ids:
      self.template2component_tbl.InsertRows(
          cnxn, TEMPLATE2COMPONENT_COLS, [(template_id, c_id) for
                                          c_id in component_ids], commit=False)
    if admin_ids:
      self.template2admin_tbl.InsertRows(
          cnxn, TEMPLATE2ADMIN_COLS, [(template_id, admin_id) for
                                      admin_id in admin_ids], commit=False)
    if field_values:
      self.template2fieldvalue_tbl.InsertRows(
          cnxn, TEMPLATE2FIELDVALUE_COLS, [
              (template_id, fv.field_id, fv.int_value, fv.str_value, fv.user_id,
               fv.date_value, fv.url_value) for fv in field_values],
          commit=False)

    # current phase_ids in approval_values and phases are temporary and were
    # assigned based on the order of the phases. These temporary phase_ids are
    # used to keep track of which approvals belong to which phases and are
    # updated once all phases have their real phase_ids returned from InsertRow.
    phase_id_by_tmp = {}
    if phases:
      for phase in phases:
        phase_id = self.issuephasedef_tbl.InsertRow(
            cnxn, name=phase.name, rank=phase.rank, commit=False)
        phase_id_by_tmp[phase.phase_id] = phase_id

    if approval_values:
      self.template2approvalvalue_tbl.InsertRows(
          cnxn, TEMPLATE2APPROVALVALUE_COLS,
          [(av.approval_id, template_id,
            phase_id_by_tmp.get(av.phase_id), av.status.name.lower())
           for av in approval_values],
          commit=False)

    cnxn.Commit()
    self.template_set_2lc.InvalidateKeys(cnxn, [project_id])
    return template_id

  def UpdateIssueTemplateDef(
      self, cnxn, project_id, template_id, name=None, content=None,
      summary=None, summary_must_be_edited=None, status=None, members_only=None,
      owner_defaults_to_member=None, component_required=None, owner_id=None,
      labels=None, component_ids=None, admin_ids=None, field_values=None,
      phases=None, approval_values=None):
    """Update an existing issue template definition with the given info.

    Args:
      cnxn: connection to SQL database.
      project_id: int ID of the current project.
      template_id: int ID of the issue template to update.
      name: updated name of the new issue template.
      content: updated string content of the issue template.
      summary: updated string summary of the issue template.
      summary_must_be_edited: True if the summary must be edited when this
          issue template is used to make a new issue.
      status: updated string default status of a new issue created with this
          template.
      members_only: True if only members can view this issue template.
      owner_defaults_to_member: True is issue owner should be set to member
          creating the issue.
      component_required: True if a component is required.
      owner_id: updated user_id of default owner, if any.
      labels: updated list of string labels for the new issue, if any.
      component_ids: updated list of component_ids, if any.
      admin_ids: updated list of admin_ids, if any.
      field_values: updated list of FieldValue PBs, if any.
      phases: updated list of Phase PBs, if any.
      approval_values: updated list of ApprovalValue PBs, if any.
    """
    new_values = {}
    if name is not None:
      new_values['name'] = name
    if content is not None:
      new_values['content'] = content
    if summary is not None:
      new_values['summary'] = summary
    if summary_must_be_edited is not None:
      new_values['summary_must_be_edited'] = bool(summary_must_be_edited)
    if status is not None:
      new_values['status'] = status
    if members_only is not None:
      new_values['members_only'] = bool(members_only)
    if owner_defaults_to_member is not None:
      new_values['owner_defaults_to_member'] = bool(owner_defaults_to_member)
    if component_required is not None:
      new_values['component_required'] = bool(component_required)
    if owner_id is not None:
      new_values['owner_id'] = owner_id

    self.template_tbl.Update(cnxn, new_values, id=template_id, commit=False)

    if labels is not None:
      self.template2label_tbl.Delete(
          cnxn, template_id=template_id, commit=False)
      self.template2label_tbl.InsertRows(
          cnxn, TEMPLATE2LABEL_COLS, [(template_id, label) for label in labels],
          commit=False)
    if component_ids is not None:
      self.template2component_tbl.Delete(
          cnxn, template_id=template_id, commit=False)
      self.template2component_tbl.InsertRows(
          cnxn, TEMPLATE2COMPONENT_COLS, [(template_id, c_id) for
                                          c_id in component_ids],
          commit=False)
    if admin_ids is not None:
      self.template2admin_tbl.Delete(
          cnxn, template_id=template_id, commit=False)
      self.template2admin_tbl.InsertRows(
          cnxn, TEMPLATE2ADMIN_COLS, [(template_id, admin_id) for
                                      admin_id in admin_ids],
          commit=False)
    if field_values is not None:
      self.template2fieldvalue_tbl.Delete(
          cnxn, template_id=template_id, commit=False)
      self.template2fieldvalue_tbl.InsertRows(
          cnxn, TEMPLATE2FIELDVALUE_COLS, [
              (template_id, fv.field_id, fv.int_value, fv.str_value, fv.user_id,
               fv.date_value, fv.url_value) for fv in field_values],
          commit=False)

    # we need to keep track of tmp phase_ids created at the servlet.
    phase_id_by_tmp = {}
    if phases is not None:
      self.template2approvalvalue_tbl.Delete(
          cnxn, template_id=template_id, commit=False)
      for phase in phases:
        phase_id = self.issuephasedef_tbl.InsertRow(
            cnxn, name=phase.name, rank=phase.rank, commit=False)
        phase_id_by_tmp[phase.phase_id] = phase_id

      self.template2approvalvalue_tbl.InsertRows(
          cnxn, TEMPLATE2APPROVALVALUE_COLS,
          [(av.approval_id, template_id,
            phase_id_by_tmp.get(av.phase_id), av.status.name.lower())
           for av in approval_values], commit=False)

    cnxn.Commit()
    self.template_set_2lc.InvalidateKeys(cnxn, [project_id])
    self.template_def_2lc.InvalidateKeys(cnxn, [template_id])

  def DeleteIssueTemplateDef(self, cnxn, project_id, template_id):
    """Delete the specified issue template definition."""
    self.template2label_tbl.Delete(cnxn, template_id=template_id, commit=False)
    self.template2component_tbl.Delete(
        cnxn, template_id=template_id, commit=False)
    self.template2admin_tbl.Delete(cnxn, template_id=template_id, commit=False)
    self.template2fieldvalue_tbl.Delete(
        cnxn, template_id=template_id, commit=False)
    self.template2approvalvalue_tbl.Delete(
        cnxn, template_id=template_id, commit=False)
    # We do not delete issuephasedef rows becuase these rows will be used by
    # issues that were created with this template. template2approvalvalue rows
    # can be deleted because those rows are copied over to issue2approvalvalue
    # during issue creation.
    self.template_tbl.Delete(cnxn, id=template_id, commit=False)

    cnxn.Commit()
    self.template_set_2lc.InvalidateKeys(cnxn, [project_id])
    self.template_def_2lc.InvalidateKeys(cnxn, [template_id])

  def ExpungeProjectTemplates(self, cnxn, project_id):
    template_id_rows = self.template_tbl.Select(
        cnxn, cols=['id'], project_id=project_id)
    template_ids = [row[0] for row in template_id_rows]
    self.template2label_tbl.Delete(cnxn, template_id=template_ids)
    self.template2component_tbl.Delete(cnxn, template_id=template_ids)
    # TODO(3816): Delete all other relations here.
    self.template_tbl.Delete(cnxn, project_id=project_id)

  def ExpungeUsersInTemplates(self, cnxn, user_ids, limit=None):
    """Wipes a user from the templates system.

      This method will not commit the operation. This method will
      not make changes to in-memory data.
    """
    self.template2admin_tbl.Delete(
        cnxn, admin_id=user_ids, commit=False, limit=limit)
    self.template2fieldvalue_tbl.Delete(
        cnxn, user_id=user_ids, commit=False, limit=limit)
    # template_tbl's owner_id does not reference User. All appropriate rows
    # should be deleted before rows can be safely deleted from User. No limit
    # will be applied.
    self.template_tbl.Update(
        cnxn, {'owner_id': None}, owner_id=user_ids, commit=False)


def UnpackTemplate(template_row):
  """Partially construct a template object using info from a DB row."""
  (template_id, _project_id, name, content, summary,
   summary_must_be_edited, owner_id, status,
   members_only, owner_defaults_to_member, component_required) = template_row
  template = tracker_pb2.TemplateDef()
  template.template_id = template_id
  template.name = name
  template.content = content
  template.summary = summary
  template.summary_must_be_edited = bool(
      summary_must_be_edited)
  template.owner_id = owner_id or 0
  template.status = status
  template.members_only = bool(members_only)
  template.owner_defaults_to_member = bool(owner_defaults_to_member)
  template.component_required = bool(component_required)

  return template
