#
# Copyright (C) 2017 The Android Open Source Project
#
# 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.

from __future__ import print_function

import json
import multiprocessing

TASK_COMMAND = 'command'
TASK_SYNC_NETWORK = 'sync-network'
TASK_SYNC_LOCAL = 'sync-local'

class EventLog(object):
  """Event log that records events that occurred during a repo invocation.

  Events are written to the log as a consecutive JSON entries, one per line.
  Each entry contains the following keys:
  - id: A ('RepoOp', ID) tuple, suitable for storing in a datastore.
        The ID is only unique for the invocation of the repo command.
  - name: Name of the object being operated upon.
  - task_name: The task that was performed.
  - start: Timestamp of when the operation started.
  - finish: Timestamp of when the operation finished.
  - success: Boolean indicating if the operation was successful.
  - try_count: A counter indicating the try count of this task.

  Optionally:
  - parent: A ('RepoOp', ID) tuple indicating the parent event for nested
            events.

  Valid task_names include:
  - command: The invocation of a subcommand.
  - sync-network: The network component of a sync command.
  - sync-local: The local component of a sync command.

  Specific tasks may include additional informational properties.
  """

  def __init__(self):
    """Initializes the event log."""
    self._log = []
    self._parent = None

  def Add(self, name, task_name, start, finish=None, success=None,
          try_count=1, kind='RepoOp'):
    """Add an event to the log.

    Args:
      name: Name of the object being operated upon.
      task_name: A sub-task that was performed for name.
      start: Timestamp of when the operation started.
      finish: Timestamp of when the operation finished.
      success: Boolean indicating if the operation was successful.
      try_count: A counter indicating the try count of this task.
      kind: The kind of the object for the unique identifier.

    Returns:
      A dictionary of the event added to the log.
    """
    event = {
        'id': (kind, _NextEventId()),
        'name': name,
        'task_name': task_name,
        'start_time': start,
        'try': try_count,
    }

    if self._parent:
      event['parent'] = self._parent['id']

    if success is not None or finish is not None:
        self.FinishEvent(event, finish, success)

    self._log.append(event)
    return event

  def AddSync(self, project, task_name, start, finish, success):
    """Add a event to the log for a sync command.

    Args:
      project: Project being synced.
      task_name: A sub-task that was performed for name.
                 One of (TASK_SYNC_NETWORK, TASK_SYNC_LOCAL)
      start: Timestamp of when the operation started.
      finish: Timestamp of when the operation finished.
      success: Boolean indicating if the operation was successful.

    Returns:
      A dictionary of the event added to the log.
    """
    event = self.Add(project.relpath, task_name, start, finish, success)
    if event is not None:
      event['project'] = project.name
      if project.revisionExpr:
        event['revision'] = project.revisionExpr
      if project.remote.url:
        event['project_url'] = project.remote.url
      if project.remote.fetchUrl:
        event['remote_url'] = project.remote.fetchUrl
      try:
        event['git_hash'] = project.GetCommitRevisionId()
      except Exception:
        pass
    return event

  def GetStatusString(self, success):
    """Converst a boolean success to a status string.

    Args:
      success: Boolean indicating if the operation was successful.

    Returns:
      status string.
    """
    return 'pass' if success else 'fail'

  def FinishEvent(self, event, finish, success):
    """Finishes an incomplete event.

    Args:
      event: An event that has been added to the log.
      finish: Timestamp of when the operation finished.
      success: Boolean indicating if the operation was successful.

    Returns:
      A dictionary of the event added to the log.
    """
    event['status'] =  self.GetStatusString(success)
    event['finish_time'] = finish
    return event

  def SetParent(self, event):
    """Set a parent event for all new entities.

    Args:
      event: The event to use as a parent.
    """
    self._parent = event

  def Write(self, filename):
    """Writes the log out to a file.

    Args:
      filename: The file to write the log to.
    """
    with open(filename, 'w+') as f:
      for e in self._log:
        json.dump(e, f, sort_keys=True)
        f.write('\n')


# An integer id that is unique across this invocation of the program.
_EVENT_ID = multiprocessing.Value('i', 1)

def _NextEventId():
  """Helper function for grabbing the next unique id.

  Returns:
    A unique, to this invocation of the program, integer id.
  """
  with _EVENT_ID.get_lock():
    val = _EVENT_ID.value
    _EVENT_ID.value += 1
  return val
