"""

Experiments:
    res = self.run_poll_command(command)

    res = self.run_command(command)

    subcall_stream(command)

    read_one_stream_command(command)

    gen = self.run_command2(command)
    for line in iter(gen):
        print(line, end='')

Raw method:
    print(res)
    res = subprocess.run(command, shell=True, capture_output=True)
    print('  code: ', res.returncode)
    out = clean(res.stdout)
    err = clean(res.stderr)
    print('  out:  ', out)
    print('  error:', err)
    print(' ', dir(res))

"""
import subprocess
import sys

import pkg_resources


def main():
    print('Inject')

__requires__ = 'trim'
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
    sys.exit(
        load_entry_point('django-trim==0.1', 'console_scripts', 'trim')()
    )

def inj():
    # Create the fake entry point definition
    ep = pkg_resources.EntryPoint.parse('dummy = dummy_module:DummyPlugin')

    # Create a fake distribution to insert into the global working_set
    d = pkg_resources.Distribution()

    # Add the mapping to the fake EntryPoint
    d._ep_map = {'console_scripts': {'dummy': ep}}

    # Add the fake distribution to the global working_set
    pkg_resources.working_set.add(d, 'dummy')


def test_entry_point():
    distribution = pkg_resources.Distribution(__file__)
    entry_point = pkg_resources.EntryPoint.parse(
        'plugin1=plugins.plugin1:plugin1_class',
        dist=distribution)
    distribution._ep_map = {'my_project.plugins': {'plugin1': entry_point}}
    pkg_resources.working_set.add(distribution)


def subcall_stream(cmd, fail_on_error=True):
    # Run a shell command, streaming output to STDOUT in real time
    # Expects a list style command, e.g. `["docker", "pull", "ubuntu"]`
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        bufsize=1,
        universal_newlines=True)
    for line in p.stdout:
        sys.stdout.write(line)
    p.wait()


    return exit_code

def read_one_stream_command(command, show=True):
    process = subprocess.Popen(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        ## not required when processing by read(1)
        # bufsize=1,
        ## Adding universal newlines will evoke _str_ from the `out`
        # universal_newlines=True,
    )
    res = ''
    byte_count = 0
    count = 0
    while True:
        out = process.stdout.read(1)
        if out == '' and process.poll() != None:
            break
        byte_count += 1

        if byte_count > 75_000:
            break

        if len(out) > 0:
            t = out.decode('utf')
            res += t
            if show:
                sys.stdout.write(t)
                sys.stdout.flush()
        else:
            count += 1
            if count % 20 == 0:
                print('blanked.')
                break
    # process.wait()
    return res


def run_poll_command(command):
    process = subprocess.Popen(command, stdout=subprocess.PIPE)
    while True:
        output = process.stdout.readline()
        if output == '' and process.poll() is not None:
            break
        if output:
            print(output.strip())
    rc = process.poll()
    return rc


def run_command(command):
    try:

        process = subprocess.Popen(command,
                        stdout=subprocess.PIPE,
                        stdin=subprocess.PIPE,
                        stderr=subprocess.STDOUT,
                        shell=True,
                        encoding='utf8')
        while True:
            inner = True
            pack = ''
            while inner:
                char = process.stdout.readline(1)
                pack += char
                if char == '\n':
                    print(pack, end='')
                if char is None:
                    print(pack)
                inner = False
            print(pack, end='')
            output = process.stdout.readline(64)
            if output == '' and process.poll() is not None:
                print("no output")
                break
            if output:
                print(output.strip())
        rc = process.poll()
        return rc
    except KeyboardInterrupt:
        # process.terminate()
        print('KeyboardInterrupt')


def run_command2(cmd):
    popen = subprocess.Popen(cmd,
            stdout=subprocess.PIPE,
            # stdin=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            universal_newlines=True,
            shell=True,
            encoding='utf8',
            bufsize=1,
            )
    stdout = popen.stdout
    for stdout_line in iter(stdout.readline, ""):
        yield stdout_line
        stdout.flush()

    stdout.flush()
    popen.stdout.close()
    return_code = popen.wait()
    if return_code:
        raise subprocess.CalledProcessError(return_code, cmd)
    return return_code

if __name__ == '__main__':
    main()
