# 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, "r", 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)
