# -*- 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])
