# 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:
    """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
