# Copyright (C) 2008 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.

"""Logic for tracing repo interactions.

Activated via `repo --trace ...` or `REPO_TRACE=1 repo ...`.

Temporary: Tracing is always on. Set `REPO_TRACE=0` to turn off.
To also include trace outputs in stderr do `repo --trace_to_stderr ...`
"""

import contextlib
import os
import sys
import tempfile
import time

import platform_utils


# Env var to implicitly turn on tracing.
REPO_TRACE = "REPO_TRACE"

# Temporarily set tracing to always on unless user expicitly sets to 0.
_TRACE = os.environ.get(REPO_TRACE) != "0"
_TRACE_TO_STDERR = False
_TRACE_FILE = None
_TRACE_FILE_NAME = "TRACE_FILE"
_MAX_SIZE = 70  # in MiB
_NEW_COMMAND_SEP = "+++++++++++++++NEW COMMAND+++++++++++++++++++"


def IsTraceToStderr():
    """Whether traces are written to stderr."""
    return _TRACE_TO_STDERR


def IsTrace():
    """Whether tracing is enabled."""
    return _TRACE


def SetTraceToStderr():
    """Enables tracing logging to stderr."""
    global _TRACE_TO_STDERR
    _TRACE_TO_STDERR = True


def SetTrace():
    """Enables tracing."""
    global _TRACE
    _TRACE = True


def _SetTraceFile(quiet):
    """Sets the trace file location."""
    global _TRACE_FILE
    _TRACE_FILE = _GetTraceFile(quiet)


class Trace(contextlib.ContextDecorator):
    """Used to capture and save git traces."""

    def _time(self):
        """Generate nanoseconds of time in a py3.6 safe way"""
        return int(time.time() * 1e9)

    def __init__(self, fmt, *args, first_trace=False, quiet=True):
        """Initialize the object.

        Args:
            fmt: The format string for the trace.
            *args: Arguments to pass to formatting.
            first_trace: Whether this is the first trace of a `repo` invocation.
            quiet: Whether to suppress notification of trace file location.
        """
        if not IsTrace():
            return
        self._trace_msg = fmt % args

        if not _TRACE_FILE:
            _SetTraceFile(quiet)

        if first_trace:
            _ClearOldTraces()
            self._trace_msg = f"{_NEW_COMMAND_SEP} {self._trace_msg}"

    def __enter__(self):
        if not IsTrace():
            return self

        print_msg = (
            f"PID: {os.getpid()} START: {self._time()} :{self._trace_msg}\n"
        )

        with open(_TRACE_FILE, "a") as f:
            print(print_msg, file=f)

        if _TRACE_TO_STDERR:
            print(print_msg, file=sys.stderr)

        return self

    def __exit__(self, *exc):
        if not IsTrace():
            return False

        print_msg = (
            f"PID: {os.getpid()} END: {self._time()} :{self._trace_msg}\n"
        )

        with open(_TRACE_FILE, "a") as f:
            print(print_msg, file=f)

        if _TRACE_TO_STDERR:
            print(print_msg, file=sys.stderr)

        return False


def _GetTraceFile(quiet):
    """Get the trace file or create one."""
    # TODO: refactor to pass repodir to Trace.
    repo_dir = os.path.dirname(os.path.dirname(__file__))
    trace_file = os.path.join(repo_dir, _TRACE_FILE_NAME)
    if not quiet:
        print(f"Trace outputs in {trace_file}", file=sys.stderr)
    return trace_file


def _ClearOldTraces():
    """Clear the oldest commands if trace file is too big."""
    try:
        with open(_TRACE_FILE, errors="ignore") as f:
            if os.path.getsize(f.name) / (1024 * 1024) <= _MAX_SIZE:
                return
            trace_lines = f.readlines()
    except FileNotFoundError:
        return

    while sum(len(x) for x in trace_lines) / (1024 * 1024) > _MAX_SIZE:
        for i, line in enumerate(trace_lines):
            if "END:" in line and _NEW_COMMAND_SEP in line:
                trace_lines = trace_lines[i + 1 :]
                break
        else:
            # The last chunk is bigger than _MAX_SIZE, so just throw everything
            # away.
            trace_lines = []

    while trace_lines and trace_lines[-1] == "\n":
        trace_lines = trace_lines[:-1]
    # Write to a temporary file with a unique name in the same filesystem
    # before replacing the original trace file.
    temp_dir, temp_prefix = os.path.split(_TRACE_FILE)
    with tempfile.NamedTemporaryFile(
        "w", dir=temp_dir, prefix=temp_prefix, delete=False
    ) as f:
        f.writelines(trace_lines)
    platform_utils.rename(f.name, _TRACE_FILE)
