# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd

"""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 proto 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
