# 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 sys
import os
import time
import tempfile
from contextlib import ContextDecorator

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(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)
