#!/usr/bin/env python2

# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Tails a file, and quits when inotify detects that it has been closed."""

from __future__ import print_function

import argparse
import select
import subprocess
import sys
import time
import contextlib


@contextlib.contextmanager
def WriterClosedFile(path):
    """Context manager to watch whether a file is closed by a writer.

    @param path: the path to watch.
    """
    inotify_process = subprocess.Popen(
        ['inotifywait', '-qe', 'close_write', path],
        stdout=subprocess.PIPE)

    # stdout.read is blocking, so use select.select to detect if input is
    # available.
    def IsClosed():
        """Returns whether the inotify_process.stdout file is closed."""
        read_list, _, _ = select.select([inotify_process.stdout], [], [], 0)
        return bool(read_list)

    try:
        yield IsClosed
    finally:
        inotify_process.kill()


def TailFile(path, sleep_interval, chunk_size,
             outfile=sys.stdout,
             seek_to_end=True):
    """Tails a file, and quits when there are no writers on the file.

    @param path: The path to the file to open
    @param sleep_interval: The amount to sleep in between reads to reduce
                           wasted IO
    @param chunk_size: The amount of bytes to read in between print() calls
    @param outfile: A file handle to write to.  Defaults to sys.stdout
    @param seek_to_end: Whether to start at the end of the file at |path| when
                        reading.
    """

    def ReadChunks(fh):
        """Reads all chunks from a file handle, and prints them to |outfile|.

        @param fh: The filehandle to read from.
        """
        for chunk in iter(lambda: fh.read(chunk_size), b''):
            print(chunk, end='', file=outfile)
            outfile.flush()

    with WriterClosedFile(path) as IsClosed:
        with open(path) as fh:
            if seek_to_end == True:
                fh.seek(0, 2)
            while True:
                ReadChunks(fh)
                if IsClosed():
                    # We need to read the chunks again to avoid a race condition
                    # where the writer finishes writing some output in between
                    # the ReadChunks() and the IsClosed() call.
                    ReadChunks(fh)
                    break

                # Sleep a bit to limit the number of wasted reads.
                time.sleep(sleep_interval)


def Main():
    """Main entrypoint for the script."""
    p = argparse.ArgumentParser(description=__doc__)
    p.add_argument('file', help='The file to tail')
    p.add_argument('--sleep_interval', type=float, default=0.1,
                   help='Time sleeping between file reads')
    p.add_argument('--chunk_size', type=int, default=64 * 2**10,
                   help='Bytes to read before yielding')
    p.add_argument('--from_beginning', action='store_true',
                   help='If given, read from the beginning of the file.')
    args = p.parse_args()

    TailFile(args.file, args.sleep_interval, args.chunk_size,
             seek_to_end=not args.from_beginning)


if __name__ == '__main__':
    Main()
