#!/usr/bin/env python
# -*- encoding: utf-8 -*-

#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you 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.

''' proc.py: subprocess and subprocess's stdout/stderr management '''
from threading import Thread

def _stream_process_fileno(fileno, handler):
  """ Stream handling each line from fileno
  :param filno: file object
  :param handler: a function that will be called for each line from fileno
  :return: None
  """
  while 1:
    line = fileno.readline()
    handler(line)
    if not line:
      break

def stream_process_stdout(process, handler):
  """ Stream the stdout for a process out to display
  :param process: the process to stream the stdout for
  :param handler: a function that will be called for each stdout line
  :return: None
  """
  _stream_process_fileno(process.stdout, handler)

def stream_process_stderr(process, handler):
  """ Stream the stderr for a process out to display
  :param process: the process to stream the stderr for
  :param handler: a function that will be called for each stderr line
  :return: None
  """
  _stream_process_fileno(process.stderr, handler)

def _async_stream_process_output(process, stream_fn, handler):
  """ Stream and handle the output of a process
  :param process: the process to stream the output for
  :param stream_fn: the function that applies handler to process
  :param handler: a function that will be called for each log line
  :return: None
  """
  logging_thread = Thread(target=stream_fn, args=(process, handler, ))

  # Setting the logging thread as a daemon thread will allow it to exit with the program
  # rather than blocking the exit waiting for it to be handled manually.
  logging_thread.daemon = True
  logging_thread.start()

  return logging_thread

def async_stream_process_stdout(process, handler):
  """ Stream and handler the stdout of a process
  :param process: the process to stream the stdout for
  :param handler: a function that will be called to handle each line
  :return: None
  """
  return _async_stream_process_output(process, stream_process_stdout, handler)

def async_stream_process_stderr(process, handler):
  """ Stream and handler the stderr of a process
  :param process: the process to stream the stderr for
  :param handler: a function that will be called to handle each line
  :return: None
  """
  return _async_stream_process_output(process, stream_process_stderr, handler)

class StringBuilder(object):
  def __init__(self):
    self.end = False
    self.strs = []

  def add(self, line):
    if not line:
      self.end = True
    else:
      self.strs.append(line)

  def result(self):
    while True:
      if self.end:
        return ''.join(self.strs)
      else:
        continue

def async_stdout_builder(proc):
  """ Save stdout into string builder
  :param proc: the process to save stdout for
  :return StringBuilder
  """
  stdout_builder = StringBuilder()
  async_stream_process_stdout(proc, stdout_builder.add)
  return stdout_builder

def async_stderr_builder(proc):
  """ Save stderr into string builder
  :param proc: the process to save stderr for
  :return StringBuilder
  """
  stderr_builder = StringBuilder()
  async_stream_process_stderr(proc, stderr_builder.add)
  return stderr_builder

def async_stdout_stderr_builder(proc):
  """ Save stdout and stderr into string builders
  :param proc: the process to save stdout and stderr for
  :return (StringBuilder, StringBuilder)
  """
  return async_stdout_builder(proc), async_stderr_builder(proc)
