#!/usr/bin/python
# coding=utf-8
import paramiko
import time
import sys


def get_data(host, user, password, commands):  # вытаскиваем из циски данные
    errorcode = ''
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())  # если нет хоста - добавляем
    out = []  # выхлоп будет в этом списке
    try:
        client.connect(hostname=host, username=user, password=password, look_for_keys=False,
                       allow_agent=False)  # пытаемся подключиться, look_for_keys=False, allow_agent=False - зачем-то нужны циске.
    except Exception as exept:  # в случае исключения -
        errorcode = exept  # возвращаем код и описание исключения
    else:  # усли все в порядке
        conn = client.invoke_shell()  # врубаем интерактивный шелл - с цисками только так.
        time.sleep(1)  # задержка
        conn.recv(1000)  # хаваем все, что выплюнула цика, дабы не отсвечивало
        for command in commands:  # Читаем и исполняем команды
            if command[0] == "$username":
                command[0] = user
            if command[0] == "$password":
                command[0] = password
            conn.send(command[0] + '\n')  # засылаем команду
            time.sleep(int(command[1]))  # ждем указанный таймаут
            if command[2]:  # если сказано сохранять - сохраняем выхлоп
                conn_out = conn.recv(99999999999).splitlines()  # жрем выхлоп в список, разбивая по строкам
                out_line = ""  # пустая строка для сохранения
                if len(conn_out) > 2:
                    conn_out.pop()  # обрезаем последнюю строку строку
                    conn_out.pop(0)  # Обрезаем первую строку
                if command[3]:  # если сказано комментить - комментим
                    for line in conn_out:  # перебираем все строки
                        line = "!" + line  # Добавляем в начало !
                        out_line = out_line + line + '\n'  # Собираем все мимо строк, прямо в одну строковую переменную
                else:  # Если не сказано коментить - не коментим
                    for line in conn_out:  # перебираем все строки
                        out_line = out_line + line + '\n'  # Собираем все мимо строк, прямо в одну строковую переменную
                out.append(out_line)  # Добавляем все толпой  в выхлоп
            else:  # если выхлоп нам ненужон
                conn.recv(99999999999)  # хаваем его в никуда
    finally:  # по окончании всех процедур
        client.close()  # закрываем коннектий
    return out, errorcode  # Вертаем все, что наковыряли


def read_file(in_file):
    errorcode = ""  # устанавливаем переменные
    out = []
    try:  # Пробуем открыть файл
        f = open(in_file, 'r')
    except Exception as exept:
        errorcode = exept  # не получилось - запиливаем исключение
    else:  # Если все норм - начинаем читать
        for line in f:  # Каждую линию
            sp_line = line.split(',')  # бомбим линию по разделителю в переменную
            command = []  # устанавливаем список, в котором будет храниться команда с атрибутами
            if len(sp_line) > 0:  # если элементов больше 0
                command.append(sp_line[0])  # добавляем элемент в список (это будет команда)
            if len(sp_line) > 1:  # если больше одного
                if sp_line[1].strip().isdigit():  # если 1-й элемент из цыфарок
                    command.append(int(sp_line[1].strip()))  # добавляем цыфарку, это таймаут
                else:  # если не цыфарки
                    command.append("1")  # то таймаут - 1 секунд
            if len(sp_line) > 2:  # если более 2
                if sp_line[2].strip() == "0" or sp_line[2].strip() == "False":  # 2 элемент равен фалсе или 0
                    command.append(False)  # добавляем фалсе
                else:  # если там чтой-то другое
                    command.append(True)  # добавляем трую
            if len(sp_line) > 3:  # если элементов больше 3
                if sp_line[3].strip() == "0" or sp_line[3].strip() == "False":  # 3 элемент равен фалсе или 0
                    command.append(False)  # добавляем фалсе
                else:  # если там чтой-то другое
                    command.append(True)  # добавляем трую
            if 0 < len(command) < 4:  # если элементов не хватает, добиваем фалсой
                for i in [0, 1, 2, 3]:
                    try:
                        command[i]
                    except IndexError:
                        command.append(False)
            out.append(command)
    return out, errorcode  # вертаем, что наковыряли


def arg_parse(args):  # парсим коммандную строку
    user = ""  # устанавливаем переменные
    password = ""
    cmdfile = ""
    host = ""
    errorcode = ""
    for arg in args[1:]:  # Перебираем элементы, присваивая списку все подряд
        if "\"" in arg or "\'" in arg:  # обрезаем кавычки, если есть
            arg = arg[1:-1]
        sp_arg = arg.split("=")
        if sp_arg[0].strip() not in ["host", "user", "password", "cmdfile"]:
            errorcode = errorcode + " " + arg + " Недопустимый аргумент, допустимые аргументы:" \
                                                "user=, host=, password=, cmdfile="
        elif sp_arg[0].strip() == "user":
            user = sp_arg[1].strip()
        elif sp_arg[0].strip() == "password":
            password = sp_arg[1].strip()
        elif sp_arg[0].strip() == "host":
            host = sp_arg[1].strip()
        elif sp_arg[0].strip() == "cmdfile":
            cmdfile = sp_arg[1].strip()
    if str(user) == "":  # дальше все подряд ясно
        errorcode = errorcode + "пользователь пустой "
    if str(password) == "":
        errorcode = errorcode + "пароль пустой "
    if str(cmdfile) == "":
        errorcode = errorcode + "не указан cmdfile "
    if str(host) == "":
        errorcode = errorcode + "хост пустой "
    return user, password, host, cmdfile, errorcode


if __name__ == '__main__':
    user = ''
    host = ''
    password = ''
    cmdfile = ''
    errorcode = ''
    if len(sys.argv) > 1:
        user, password, host, cmdfile, errorcode = arg_parse(sys.argv)
    commands, errorcode = read_file(cmdfile)
    if errorcode:
        exit(errorcode)
    try:
        commands
    except NameError:
        commands = [['login', 0, False, True],
                    [user, 0, False, True],
                    [password, 0, False, True],
                    ['terminal pager 0', 1, False, True],
                    ['show version', 5, True, True],
                    ['show flash', 5, True, True],
                    ['show configuration', 10, True, False]]
    output, errorcode = get_data(host, user, password, commands)
    if errorcode == "0":
        for out in output:
            print out
    else:
        print("errorcode = " + str(errorcode))
