#!/usr/bin/env python3

"""Test odirectcmodule using bufsock."""

import os
import sys
sys.path.insert(0, os.path.expanduser('~/lib'))
sys.path.insert(0, os.path.expanduser('.'))

import bufsock  # noqa: disable=E402
import odirect  # noqa: disable=E402
import readline0  # noqa: disable=E402

underlying_chunk_size = 1 << 19
toplevel_chunk_size = 12345

arrow = "===============>"

found_error = 0
for filename in readline0.readline0():
    # sys.stderr.write("comparing filename %s's data via odirect+bufsock and via normal python file I/O ...\n" % filename)
    odirect_file = odirect.odirect(filename, b'rbd', underlying_chunk_size)
    bufsock_file = bufsock.bufsock(odirect_file, chunk_len=underlying_chunk_size)
    regular_file = open(filename, 'rb')
    odirect_offset = 0
    regular_offset = 0
    while 1:
        # Note: assumption here is that both file I/O methods are going to return all that they can - EG, if we ask for
        # 512K, we're going to get 512K until we hit EOF.  If the two methods return short blocks inconsistently, this
        # test may appear to have failed, when it wouldn't if we were being careful about potential blocking
        # differences
        odirect_block = bufsock_file.read(toplevel_chunk_size)
        regular_block = regular_file.read(toplevel_chunk_size)
        if odirect_block != regular_block:
            string = 'Error on file %s, odirect len: %d, regular I/O len: %d, req\'d block size: %d' + \
                ', odir offset: %d, reg offset: %d\n'
            sys.stderr.write(string % (
                filename,
                len(odirect_block),
                len(regular_block),
                toplevel_chunk_size,
                odirect_offset,
                regular_offset,
            ))
            found_error = 1
        odirect_offset += len(odirect_block)
        regular_offset += len(regular_block)
        if not odirect_block:
            # sys.stdout.write('Empty block')
            # sys.stdout.flush()
            break
        # hex_dump(block)
        # sys.stdout.write('%d ' % len(odirect_block))
        # sys.stdout.flush()
    del odirect_file
    regular_file.close()

sys.exit(found_error)