text: # Copyright 2016 The Oppia Authors. All Rights Reserved.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #      http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS-IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  """Domain objects for feedback models."""
  
  from __future__ import absolute_import  # pylint: disable=import-only-modules
  from __future__ import unicode_literals  # pylint: disable=import-only-modules
  
  from core.domain import user_services
  import python_utils
  import utils
  
  
  class FeedbackThread(python_utils.OBJECT):
      """Domain object for a feedback thread.
  
      Attributes:
          id: str. The feedback thread ID.
          entity_type: str. The type of entity the feedback thread is linked to.
          entity_id: str. The id of the entity.
          state_name: str. The name of the state associated with
              the feedback thread.
          original_author_id: str. The ID of the original author.
          status: str. The current status of the thread. Status should
              be one of core.storage.feedback.gae_models.STATUS_CHOICES.
          subject: str. The subject of the feedback thread.
          summary: str. A summary of the feedback thread.
          has_suggestion: bool. Whether the feedback thread includes a
              suggestion.
          message_count: int. The number of messages posted onto the thread.
          created_on: datetime.datetime. The time when the feedback thread was
              created.
          last_updated: datetime.datetime. The time when the feedback thread
              was last updated.
          last_nonempty_message_text: str|None. Cached text of the last message in
              the thread with non-empty content, or None if there is no such
              message.
          last_nonempty_message_author_id: str|None. Cached ID for the user of the
              last message in the thread with non-empty content, or None if the
              message was made anonymously or if there is no such message.
      """
  
      def __init__(
              self, thread_id, entity_type, entity_id, state_name,
              original_author_id, status, subject, summary, has_suggestion,
              message_count, created_on, last_updated, last_nonempty_message_text,
              last_nonempty_message_author_id):
          """Initializes a FeedbackThread object."""
  
          self.id = thread_id
          self.entity_type = entity_type
          self.entity_id = entity_id
          self.state_name = state_name
          self.original_author_id = original_author_id
          self.status = status
          self.subject = subject
          self.summary = summary
          self.has_suggestion = has_suggestion
          self.message_count = message_count
  
          self.created_on = created_on
          self.last_updated = last_updated
          self.last_nonempty_message_text = last_nonempty_message_text
          self.last_nonempty_message_author_id = last_nonempty_message_author_id
  
      def to_dict(self):
          """Returns a dict representation of this FeedbackThread object.
  
          Returns:
              dict. A dict representation of the FeedbackThread object.
          """
          return {
              'last_updated_msecs': (
                  utils.get_time_in_millisecs(self.last_updated)),
              'original_author_username': (
                  user_services.get_username(self.original_author_id)
                  if self.original_author_id else None),
              'state_name': self.state_name,
              'status': self.status,
              'subject': self.subject,
              'summary': self.summary,
              'thread_id': self.id,
              'message_count': self.message_count,
              'last_nonempty_message_text': self.last_nonempty_message_text,
              'last_nonempty_message_author': (
                  user_services.get_username(self.last_nonempty_message_author_id)
                  if self.last_nonempty_message_author_id else None),
          }
  
      def _get_full_message_id(self, message_id):
          """Returns the full id of the message.
  
          Args:
              message_id: int. The id of the message for which we have to fetch
                  the complete message id.
  
          Returns:
              str. The full id corresponding to the given message id.
          """
          return '.'.join([self.id, python_utils.UNICODE(message_id)])
  
      def get_last_two_message_ids(self):
          """Returns the full message ids of the last two messages of the thread.
          If the thread has only one message, the id of the second last message is
          None.
  
          Returns:
              list(str|None). The ids of the last two messages of the thread. If
              the message does not exist, None is returned.
          """
          return [
              self._get_full_message_id(i) if i >= 0 else None
              for i in python_utils.RANGE(
                  self.message_count - 1, self.message_count - 3, -1)
          ]
  
  
  class FeedbackMessage(python_utils.OBJECT):
      """Domain object for a feedback message.
  
      Attributes:
          full_message_id: str. The ID of the feedback message.
          thread_id: str. The ID of the feedback thread containing this
              message.
          message_id: str. The ID of the feedback thread message.
          author_id: str. The ID of the message's author.
          updated_status: str. The new status of the feedback thread.
          updated_subject: str. The new feedback thread subject.
          text: str. The text for the full feedback thread message.
          created_on: datetime.datetime. The time when the feedback message was
              created.
          last_updated: datetime.datetime. The time when the feedback message
              was last updated.
          received_via_email: bool. Whether the feedback was received via email.
      """
  
      def __init__(
              self, full_message_id, thread_id, message_id, author_id,
              updated_status, updated_subject, text, created_on,
              last_updated, received_via_email):
          self.id = full_message_id
          self.thread_id = thread_id
          self.message_id = message_id
          self.author_id = author_id
          self.updated_status = updated_status
          self.updated_subject = updated_subject
          self.text = text
          self.created_on = created_on
          self.last_updated = last_updated
          self.received_via_email = received_via_email
  
      @property
      def entity_id(self):
          """Returns the entity ID corresponding to this FeedbackMessage instance.
  
          Returns:
              str. The entity_id.
          """
          return self.id.split('.')[1]
  
      @property
      def entity_type(self):
          """Returns the entity type corresponding to this FeedbackMessage
          instance.
  
          Returns:
              str. The entity_type.
          """
          return self.id.split('.')[0]
  
      def to_dict(self):
          """Returns a dict representation of this FeedbackMessage object.
  
          Returns:
              dict. Dict representation of the FeedbackMessage object.
          """
          return {
              'author_username': (
                  user_services.get_username(self.author_id)
                  if self.author_id else None),
              'created_on_msecs': utils.get_time_in_millisecs(self.created_on),
              'entity_type': self.entity_type,
              'entity_id': self.entity_id,
              'message_id': self.message_id,
              'text': self.text,
              'updated_status': self.updated_status,
              'updated_subject': self.updated_subject
          }
  
  
  class FeedbackAnalytics(python_utils.OBJECT):
      """Domain object representing feedback analytics for a specific entity.
  
      Attributes:
          entity_type: str. The type of entity the feedback thread is linked to.
          entity_id: str. The id of the entity.
          num_open_threads: int. The number of open threads associated with the
              entity.
          num_total_threads: int. The total number of threads associated with the
              entity (regardless of status).
      """
  
      def __init__(
              self, entity_type, entity_id, num_open_threads, num_total_threads):
          """Initializes a FeedbackAnalytics object."""
  
          self.id = entity_id
          self.entity_type = entity_type
          self.num_open_threads = num_open_threads
          self.num_total_threads = num_total_threads
  
      def to_dict(self):
          """Returns the numbers of threads in the FeedbackAnalytics object.
  
          Attributes:
              dict. Dict representation of the numbers of threads in the
                  FeedbackAnalytics object.
          """
          return {
              'num_open_threads': self.num_open_threads,
              'num_total_threads': self.num_total_threads
          }
  
  
  class FeedbackMessageReference(python_utils.OBJECT):
      """Domain object for feedback message references.
  
      Attributes:
          entity_type: str. The type of entity the feedback thread is linked to.
          entity_id: str. The id of the entity.
          thread_id: str. The ID of the feedback thread.
          message_id: str. The ID of the feedback thread message.
      """
  
      def __init__(self, entity_type, entity_id, thread_id, message_id):
          """Initializes FeedbackMessageReference object."""
          self.entity_type = entity_type
          self.entity_id = entity_id
          self.thread_id = thread_id
          self.message_id = message_id
  
      def to_dict(self):
          """Returns dict representation of the FeedbackMessageReference object.
  
          Returns:
              dict. Dict representation of the FeedbackMessageReference object.
          """
          return {
              'entity_type': self.entity_type,
              'entity_id': self.entity_id,
              'thread_id': self.thread_id,
              'message_id': self.message_id
          }
  
  
  class FeedbackThreadSummary(python_utils.OBJECT):
      """Domain object for the summary of a particular thread.
  
      Attributes:
          status: str. The status of the thread.
          original_author_id: str. The id of the original author of the thread.
          last_updated: datetime.datetime. When was the thread last updated.
          last_message_text: str. The text of the last message.
          total_message_count: int. The total number of messages in the thread.
          last_message_is_read: bool. Whether the last message is read by the
              user.
          second_last_message_is_read: bool. Whether the second last message is
              read by the user,
          author_last_message: str. The name of the author of the last message.
          author_second_last_message: str. The name of the author of the second
              last message.
          exploration_title: str. The title of the exploration to which
              exploration belongs.
          exploration_id: str. The id of the exploration associated to the thread.
          thread_id: str. The id of the thread this dict is describing.
      """
  
      def __init__(
              self, status, original_author_id, last_updated, last_message_text,
              total_message_count, last_message_is_read,
              second_last_message_is_read, author_last_message,
              author_second_last_message, exploration_title, exploration_id,
              thread_id):
          self.status = status
          self.original_author_id = original_author_id
          self.last_updated = last_updated
          self.last_message_text = last_message_text
          self.total_message_count = total_message_count
          self.last_message_is_read = last_message_is_read
          self.second_last_message_is_read = second_last_message_is_read
          self.author_last_message = author_last_message
          self.author_second_last_message = author_second_last_message
          self.exploration_title = exploration_title
          self.exploration_id = exploration_id
          self.thread_id = thread_id
  
      def to_dict(self):
          """Returns dict representation of the FeedbackThreadSummary object.
  
          Returns:
              dict. Dict representation of the FeedbackThreadSummary object.
          """
          return {
              'status': self.status,
              'original_author_id': self.original_author_id,
              'last_updated_msecs': (
                  utils.get_time_in_millisecs(self.last_updated)),
              'last_message_text': self.last_message_text,
              'total_message_count': self.total_message_count,
              'last_message_is_read': self.last_message_is_read,
              'second_last_message_is_read': self.second_last_message_is_read,
              'author_last_message': self.author_last_message,
              'author_second_last_message': self.author_second_last_message,
              'exploration_title': self.exploration_title,
              'exploration_id': self.exploration_id,
              'thread_id': self.thread_id,
          }
  