##-*-coding:utf-8*-*

import sys
from pyeole import process
from subprocess import PIPE
from pytest import raises

class FakePopen:
    returncode = 0
    def __init__(self, cmd, stdin, stdout, stderr, env):
        global FAKE_POPEN_CMD, FAKE_POPEN_STDIN, FAKE_POPEN_STDOUT, \
                FAKE_POPEN_STDERR, FAKE_POPEN_ENV
        FAKE_POPEN_CMD.append(cmd)
        FAKE_POPEN_STDIN.append(stdin)
        FAKE_POPEN_STDOUT.append(stdout)
        FAKE_POPEN_STDERR.append(stderr)
        FAKE_POPEN_ENV.append(env)
        if cmd[0] == '/usr/bin/lxc-info':
            #for creole_test_container
            self.stdout = cmd[2]+' is running'
        else:
            self.stdout = 'stdout'

    def communicate(self, stdin):
        global FAKE_POPEN_STDIN_CONT
        FAKE_POPEN_STDIN_CONT.append(stdin)
        return self.stdout, 'stderr'

class FakePopenRaise:
    def __init__(*args, **argsv):
        raise ValueError('you must set Popen class')

class FakeCreoleClient:
    def get_container(self, container):
        return {'path': '/path/container', 'ip': '192.0.2.30',
                'name': container, 'group': container}

class FakeCreoleClientRoot:
    def get_container(self, container):
        return {'path': '', 'ip': '127.0.0.1',
                'name': container, 'group': container}

class FakeCreoleClientRaise:
    def get_container(self, container):
        raise ValueError('you must set CreoleClient class')

class FakeSocket:
    def __init__(self, *args):
        pass

    def __getattr__(self, name, *args):
        def function(*args):
            pass
        return function

class FakeSocketRaise:
    def __init__(*args, **argsv):
        raise ValueError('you must set Socket class')

class fake_sys_stdout:
    mode = 'w'

class fake_sys_stdout_binaire:
    mode = 'wb'

def fake_openpty():
    global FAKE_OPENPTY
    FAKE_OPENPTY.append(True)
    return 'nstdin', 'nstderr'

def setup_function(function):
    global FAKE_POPEN_CMD, FAKE_POPEN_STDIN, FAKE_POPEN_STDOUT, \
            FAKE_POPEN_STDERR, FAKE_POPEN_ENV, FAKE_POPEN_STDIN_CONT, \
            FAKE_OPENPTY
    FAKE_POPEN_CMD = []
    FAKE_POPEN_STDIN = []
    FAKE_POPEN_STDOUT = []
    FAKE_POPEN_STDERR = []
    FAKE_POPEN_ENV = []
    FAKE_POPEN_STDIN_CONT = []
    FAKE_OPENPTY = []
    process.Popen = FakePopenRaise
    process.sys_stdout = fake_sys_stdout
    process.openpty = fake_openpty
    process.creole_client = FakeCreoleClientRaise()
    process.socket = FakeSocketRaise

##############################################################################
# system_code
##############################################################################

def test_system_code_single():
    process.Popen = FakePopen
    cmd = 'ls'
    assert process.system_code(cmd) == 0
    assert FAKE_POPEN_CMD == [cmd]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [None]
    assert FAKE_POPEN_STDERR == [None]
    assert FAKE_POPEN_ENV == [None]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

def test_system_code_list():
    process.Popen = FakePopen
    cmd = ['ls', '/home']
    assert process.system_code(cmd) == 0
    assert FAKE_POPEN_CMD == [cmd]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [None]
    assert FAKE_POPEN_STDERR == [None]
    assert FAKE_POPEN_ENV == [None]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

def test_system_code_env():
    process.Popen = FakePopen
    cmd = ['ls', '/home']
    env = {'LC_ALL': 'fr_FR.UTF-8'}
    assert process.system_code(cmd, env=env) == 0
    assert FAKE_POPEN_CMD == [['ls', '/home']]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [None]
    assert FAKE_POPEN_STDERR == [None]
    assert FAKE_POPEN_ENV == [env]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

def test_system_code_context():
    process.Popen = FakePopen
    cmd = ['ls', '/home']
    env = {'LC_ALL': 'fr_FR.UTF-8'}
    assert process.system_code(cmd, context=False) == 0
    assert FAKE_POPEN_CMD == [['ls', '/home']]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [None]
    assert FAKE_POPEN_STDERR == [None]
    assert FAKE_POPEN_ENV == [None]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

if sys.version_info[0] < 3:
    def test_system_code_stdin():
        process.Popen = FakePopen
        cmd = ['ls', '/home']
        stdin = 'text'
        assert process.system_code(cmd, stdin=stdin) == 0
        assert FAKE_POPEN_CMD == [cmd]
        assert FAKE_POPEN_STDIN == [PIPE]
        assert FAKE_POPEN_STDOUT == [None]
        assert FAKE_POPEN_STDERR == [None]
        assert FAKE_POPEN_ENV == [None]
        assert FAKE_POPEN_STDIN_CONT == [stdin]
        assert FAKE_OPENPTY == []

# def test_system_code_pty():
#     process.Popen = FakePopen
#     cmd = ['ls', '/home']
#     assert process.system_code(cmd, pty=True) == 0
#     assert FAKE_POPEN_CMD == [cmd]
#     assert FAKE_POPEN_STDIN == ['nstdin']
#     assert FAKE_POPEN_STDOUT == [None]
#     assert FAKE_POPEN_STDERR == ['nstderr']
#     assert FAKE_POPEN_ENV == [None]
#     assert FAKE_POPEN_STDIN_CONT == [None]
#     assert FAKE_OPENPTY == [True]

# def test_system_code_pty_stdin():
#     process.Popen = FakePopen
#     cmd = ['ls', '/home']
#     raises(ValueError, "process.system_code(cmd, stdin='text', pty=True)")

# def test_system_code_container():
#     process.Popen = FakePopen
#     process.creole_client = FakeCreoleClient()
#     process.socket = FakeSocket
#     cmd = ['ls', '/home']
#     assert process.system_code(cmd, container='container') == 0
#     assert FAKE_POPEN_CMD == [['/usr/bin/lxc-info', '-n', 'container'],
#             ['/usr/bin/ssh', '-q', '-o', 'LogLevel=ERROR', '-o',
#                 'StrictHostKeyChecking=no', 'root@192.0.2.30', 'ls', '/home']]
#     assert FAKE_POPEN_STDIN == [PIPE, PIPE]
#     assert FAKE_POPEN_STDOUT == [PIPE, None]
#     assert FAKE_POPEN_STDERR == [PIPE, None]
#     assert FAKE_POPEN_ENV == [None, None]
#     assert FAKE_POPEN_STDIN_CONT == [None, None]
#     assert FAKE_OPENPTY == []

def test_system_code_container_context():
    process.Popen = FakePopen
    process.creole_client = FakeCreoleClient()
    process.socket = FakeSocket
    cmd = ['ls', '/home']
    assert process.system_code(cmd, container='container', context=False) == 0
    assert FAKE_POPEN_CMD == [['chroot', '/path/container', 'ls', '/home']]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [None]
    assert FAKE_POPEN_STDERR == [None]
    assert FAKE_POPEN_ENV == [None]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

def test_system_code_container_context_env():
    process.Popen = FakePopen
    process.creole_client = FakeCreoleClient()
    process.socket = FakeSocket
    cmd = ['ls', '/home']
    env = {'LC_ALL': 'fr_FR.UTF-8'}
    assert process.system_code(cmd, container='container', context=False,
            env=env) == 0
    assert FAKE_POPEN_CMD == [['chroot', '/path/container', 'ls', '/home']]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [None]
    assert FAKE_POPEN_STDERR == [None]
    assert FAKE_POPEN_ENV == [env]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

# def test_system_code_container_pty():
#     process.Popen = FakePopen
#     process.creole_client = FakeCreoleClient()
#     process.socket = FakeSocket
#     cmd = ['ls', '/home']
#     assert process.system_code(cmd, container='container', pty=True) == 0
#     assert FAKE_POPEN_CMD == [['/usr/bin/lxc-info', '-n', 'container'],
#             ['/usr/bin/ssh', '-t', '-q', '-o', 'LogLevel=ERROR', '-o',
#                 'StrictHostKeyChecking=no', 'root@192.0.2.30', 'ls', '/home']]
#     assert FAKE_POPEN_STDIN == [PIPE, 'nstdin']
#     assert FAKE_POPEN_STDOUT == [PIPE, None]
#     assert FAKE_POPEN_STDERR == [PIPE, 'nstderr']
#     assert FAKE_POPEN_ENV == [None, None]
#     assert FAKE_POPEN_STDIN_CONT == [None, None]
#     assert FAKE_OPENPTY == [True]

def test_system_code_wb():
    process.sys_stdout = fake_sys_stdout_binaire
    process.Popen = FakePopen
    cmd = ['ls', '/home']
    assert process.system_code(cmd) == 0
    assert FAKE_POPEN_CMD == [cmd]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [PIPE]
    assert FAKE_POPEN_STDERR == [PIPE]
    assert FAKE_POPEN_ENV == [None]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

##############################################################################
# system_out
##############################################################################
def test_system_out_single():
    process.Popen = FakePopen
    cmd = 'ls'
    assert process.system_out(cmd) == (0, 'stdout', 'stderr')
    assert FAKE_POPEN_CMD == [cmd]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [PIPE]
    assert FAKE_POPEN_STDERR == [PIPE]
    assert FAKE_POPEN_ENV == [None]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

def test_system_out_list():
    process.Popen = FakePopen
    cmd = ['ls', '/home']
    assert process.system_out(cmd) == (0, 'stdout', 'stderr')
    assert FAKE_POPEN_CMD == [cmd]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [PIPE]
    assert FAKE_POPEN_STDERR == [PIPE]
    assert FAKE_POPEN_ENV == [None]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

def test_system_out_env():
    process.Popen = FakePopen
    cmd = ['ls', '/home']
    env = {'LC_ALL': 'fr_FR.UTF-8'}
    assert process.system_out(cmd, env=env) == (0, 'stdout', 'stderr')
    assert FAKE_POPEN_CMD == [['ls', '/home']]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [PIPE]
    assert FAKE_POPEN_STDERR == [PIPE]
    assert FAKE_POPEN_ENV == [env]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

def test_system_out_context():
    process.Popen = FakePopen
    cmd = ['ls', '/home']
    env = {'LC_ALL': 'fr_FR.UTF-8'}
    assert process.system_out(cmd, context=False) == (0, 'stdout', 'stderr')
    assert FAKE_POPEN_CMD == [['ls', '/home']]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [PIPE]
    assert FAKE_POPEN_STDERR == [PIPE]
    assert FAKE_POPEN_ENV == [None]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

if sys.version_info[0] < 3:
    def test_system_out_stdin():
        process.Popen = FakePopen
        cmd = ['ls', '/home']
        stdin = 'text'
        assert process.system_out(cmd, stdin=stdin) == (0, 'stdout', 'stderr')
        assert FAKE_POPEN_CMD == [cmd]
        assert FAKE_POPEN_STDIN == [PIPE]
        assert FAKE_POPEN_STDOUT == [PIPE]
        assert FAKE_POPEN_STDERR == [PIPE]
        assert FAKE_POPEN_ENV == [None]
        assert FAKE_POPEN_STDIN_CONT == [stdin]
        assert FAKE_OPENPTY == []

# def test_system_out_pty():
#     process.Popen = FakePopen
#     cmd = ['ls', '/home']
#     assert process.system_out(cmd, pty=True) == (0, 'stdout', 'stderr')
#     assert FAKE_POPEN_CMD == [cmd]
#     assert FAKE_POPEN_STDIN == ['nstdin']
#     assert FAKE_POPEN_STDOUT == [PIPE]
#     assert FAKE_POPEN_STDERR == ['nstderr']
#     assert FAKE_POPEN_ENV == [None]
#     assert FAKE_POPEN_STDIN_CONT == [None]
#     assert FAKE_OPENPTY == [True]

# def test_system_out_pty_stdin():
#     process.Popen = FakePopen
#     cmd = ['ls', '/home']
#     raises(ValueError, "process.system_out(cmd, stdin='text', pty=True)")

# def test_system_out_container():
#     process.Popen = FakePopen
#     process.creole_client = FakeCreoleClient()
#     process.socket = FakeSocket
#     cmd = ['ls', '/home']
#     assert process.system_out(cmd, container='container') == (0, 'stdout', 'stderr')
#     assert FAKE_POPEN_CMD == [['/usr/bin/lxc-info', '-n', 'container'],
#             ['/usr/bin/ssh', '-q', '-o', 'LogLevel=ERROR', '-o',
#                 'StrictHostKeyChecking=no', 'root@192.0.2.30', 'ls', '/home']]
#     assert FAKE_POPEN_STDIN == [PIPE, PIPE]
#     assert FAKE_POPEN_STDOUT == [PIPE, PIPE]
#     assert FAKE_POPEN_STDERR == [PIPE, PIPE]
#     assert FAKE_POPEN_ENV == [None, None]
#     assert FAKE_POPEN_STDIN_CONT == [None, None]
#     assert FAKE_OPENPTY == []

def test_system_out_container_context():
    process.Popen = FakePopen
    process.creole_client = FakeCreoleClient()
    process.socket = FakeSocket
    cmd = ['ls', '/home']
    assert process.system_out(cmd, container='container', context=False) == \
            (0, 'stdout', 'stderr')
    assert FAKE_POPEN_CMD == [['chroot', '/path/container', 'ls', '/home']]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [PIPE]
    assert FAKE_POPEN_STDERR == [PIPE]
    assert FAKE_POPEN_ENV == [None]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

def test_system_out_container_context_env():
    process.Popen = FakePopen
    process.creole_client = FakeCreoleClient()
    process.socket = FakeSocket
    cmd = ['ls', '/home']
    env = {'LC_ALL': 'fr_FR.UTF-8'}
    assert process.system_out(cmd, container='container', context=False,
            env=env) == (0, 'stdout', 'stderr')
    assert FAKE_POPEN_CMD == [['chroot', '/path/container', 'ls', '/home']]
    assert FAKE_POPEN_STDIN == [PIPE]
    assert FAKE_POPEN_STDOUT == [PIPE]
    assert FAKE_POPEN_STDERR == [PIPE]
    assert FAKE_POPEN_ENV == [env]
    assert FAKE_POPEN_STDIN_CONT == [None]
    assert FAKE_OPENPTY == []

# def test_system_out_container_pty():
#     process.Popen = FakePopen
#     process.creole_client = FakeCreoleClient()
#     process.socket = FakeSocket
#     cmd = ['ls', '/home']
#     assert process.system_out(cmd, container='container', pty=True) == (0, 'stdout', 'stderr')
#     assert FAKE_POPEN_CMD == [['/usr/bin/lxc-info', '-n', 'container'],
#             ['/usr/bin/ssh', '-t', '-q', '-o', 'LogLevel=ERROR', '-o',
#                 'StrictHostKeyChecking=no', 'root@192.0.2.30', 'ls', '/home']]
#     assert FAKE_POPEN_STDIN == [PIPE, 'nstdin']
#     assert FAKE_POPEN_STDOUT == [PIPE, PIPE]
#     assert FAKE_POPEN_STDERR == [PIPE, 'nstderr']
#     assert FAKE_POPEN_ENV == [None, None]
#     assert FAKE_POPEN_STDIN_CONT == [None, None]
#     assert FAKE_OPENPTY == [True]

##############################################################################
# quote
##############################################################################

def test_system_code_nocontainer_quote():
    process.Popen = FakePopen
    cmd = ['echo', 'test \" test']
    assert process.system_code(cmd) == 0
    assert FAKE_POPEN_CMD == [cmd]

# def test_system_code_container_quote():
#     process.Popen = FakePopen
#     process.creole_client = FakeCreoleClient()
#     process.socket = FakeSocket
#     cmd = ['echo', 'test \" test']
#     assert process.system_code(cmd, container='container') == 0
#     assert FAKE_POPEN_CMD == [['/usr/bin/lxc-info', '-n', 'container'],
#             ['/usr/bin/ssh', '-q', '-o', 'LogLevel=ERROR', '-o',
#                 'StrictHostKeyChecking=no', 'root@192.0.2.30', 'echo', 'test \\\" test']]

#from os import unlink
#from os.path import isfile
#from creole.eosfunc import load_container_var
#from pyeole.process import system_code, system_out
#from pyeole.service import service_code
#
#test_file = '/tmp/test_process'
#
#def _delete_test_file():
#    if isfile(test_file):
#        unlink(test_file)
#
#def test_system_code_ok():
#    assert system_code(['echo']) == 0
#
#def test_system_code_err():
#    _delete_test_file()
#    assert system_code(['ls', test_file]) == 2
#
#def test_system_out_ok():
#    output = system_out(['echo', '-n', 'coucou'])
#    assert output[0] == 0
#    assert output[1] == 'coucou'
#    assert output[2] == ''
#
#def test_system_out_err():
#    _delete_test_file()
#    output = system_out(['ls', test_file])
#    assert output[0] == 2
#    assert output[1] == ''
#    assert test_file in output[2]
#
#def test_system_out_stdin():
#    assert system_out(['cat'], stdin='hello')[1] == 'hello'
#
#def test_service_code():
#    if isfile('/etc/init.d/ntp'):
#        service_code('ntp', 'stop')
#        assert service_code('ntp', 'status') != 0
#        service_code('ntp', 'start')
#        assert service_code('ntp', 'status') == 0
#
#def test_containers():
#    """
#    Vérifie que la sortie est identique quelque soit le mode
#    """
#    containers = load_container_var()
#    for container in containers:
#        # recherche du 1er conteneur différent de root
#        if container.startswith("container_path_") and not container.endswith('root'):
#            cont = container.split('_')[-1]
#            test1 = system_out(['echo', '////"\''], container=cont)
#            test2 = system_out(['echo', '////"\''], container='root')
#            assert test1 == test2
#            break
#
