# 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.

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
