# -*- coding:utf-8 -*-
#
# 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.

from __future__ import print_function
import os
import select
import subprocess
import sys

import platform_utils

active = False
pager_process = None
old_stdout = None
old_stderr = None


def RunPager(globalConfig):
  if not os.isatty(0) or not os.isatty(1):
    return
  pager = _SelectPager(globalConfig)
  if pager == '' or pager == 'cat':
    return

  if platform_utils.isWindows():
    _PipePager(pager)
  else:
    _ForkPager(pager)


def TerminatePager():
  global pager_process, old_stdout, old_stderr
  if pager_process:
    sys.stdout.flush()
    sys.stderr.flush()
    pager_process.stdin.close()
    pager_process.wait()
    pager_process = None
    # Restore initial stdout/err in case there is more output in this process
    # after shutting down the pager process
    sys.stdout = old_stdout
    sys.stderr = old_stderr


def _PipePager(pager):
  global pager_process, old_stdout, old_stderr
  assert pager_process is None, "Only one active pager process at a time"
  # Create pager process, piping stdout/err into its stdin
  pager_process = subprocess.Popen([pager], stdin=subprocess.PIPE, stdout=sys.stdout, stderr=sys.stderr)
  old_stdout = sys.stdout
  old_stderr = sys.stderr
  sys.stdout = pager_process.stdin
  sys.stderr = pager_process.stdin


def _ForkPager(pager):
  global active
  # This process turns into the pager; a child it forks will
  # do the real processing and output back to the pager. This
  # is necessary to keep the pager in control of the tty.
  #
  try:
    r, w = os.pipe()
    pid = os.fork()
    if not pid:
      os.dup2(w, 1)
      os.dup2(w, 2)
      os.close(r)
      os.close(w)
      active = True
      return

    os.dup2(r, 0)
    os.close(r)
    os.close(w)

    _BecomePager(pager)
  except Exception:
    print("fatal: cannot start pager '%s'" % pager, file=sys.stderr)
    sys.exit(255)


def _SelectPager(globalConfig):
  try:
    return os.environ['GIT_PAGER']
  except KeyError:
    pass

  pager = globalConfig.GetString('core.pager')
  if pager:
    return pager

  try:
    return os.environ['PAGER']
  except KeyError:
    pass

  return 'less'


def _BecomePager(pager):
  # Delaying execution of the pager until we have output
  # ready works around a long-standing bug in popularly
  # available versions of 'less', a better 'more'.
  #
  _a, _b, _c = select.select([0], [], [0])

  os.environ['LESS'] = 'FRSX'

  try:
    os.execvp(pager, [pager])
  except OSError:
    os.execv('/bin/sh', ['sh', '-c', pager])
