#!/usr/bin/env python
#
# vim: set ts=4 sw=4 sts=0 et :

from __future__ import print_function

import pexpect, os, sys, getopt, time, re
import pdb


def usage(code):
    print('Usage: wait-ios-serial [-i prompt] -s server [-p port] [-i prompt]\n', file=sys.stderr)
    sys.exit(code)

def main(argv):
    # Options
    server = 'localhost'
    port = 23
    tmout = 300 # Total timeout
    cycle = 10  # Cycle timeout
    input = '>'
    username = 'cisco'
    password = 'cisco'
    debug = 0

    # Local vars
    tries = 0

    # Cmdline parsing
    try:
        opts, args = getopt.getopt(argv,"c:di:p:s:t:u:P:",["cycle=","debug","input=","port=","server=","timeout=","username=","password="])
    except getopt.GetoptError:
        usage(2)
    for opt, arg in opts:
        if opt in ('-c','--cycle'):
            cycle = int(arg)
        if opt in ('-d','--debug'):
            debug += 1
        if opt in ('-i','--input'):
            input = arg
        if opt in ('-p','--port'):
            port = arg
        if opt in ('-s','--server'):
            server = arg
        if opt in ('-t','--timeout'):
            tmout = int(arg)
        if opt in ('-u','--username'):
            username = arg
        if opt in ('-P','--password'):
            password = arg
    if server == '':
        usage(2)

    if debug > 0:
        print('Input to look for is: "%s"' % input, file=sys.stderr)

    # The meat
    child = pexpect.spawn('telnet %s %s' % (server,port), timeout=cycle)

    if debug > 0:
        child.logfile = sys.stdout
    try:
        child.expect("Escape character is .*", timeout=cycle)
    except pexpect.EOF as e:
        exit(1)

    # Wait for the system to boot
    first = last = time.time()
    expr = re.compile(input)
    userre = re.compile('^[Uu]sername: ')
    passre = re.compile('^[Pp]assword: ')

    child.send("\r")
    done = False
    while not done:
        try:
            lines = child.read_nonblocking(size=100)
            lines = re.sub('\r','',lines)
            if len(lines) == 0:
                continue
            for line in lines.split('\n'):
                if debug > 1:
                    print('\nLine is "%s"' % line, file=sys.stderr)
                    print('\nLen is %d' % len(line), file=sys.stderr)
                if expr.match(line):
                    if debug > 0:
                        print('\nExiting, match found in line: "%s"' % line, file=sys.stderr)
                    done = True
                    continue
                elif userre.match(line):
                    child.sendline(username)
                    last = time.time()
                elif passre.match(line):
                    child.sendline(password)
                    last = time.time()
            if len(lines) > 0:
                #print('\nGot something, resetting counter: "%s"' % line, file=sys.stderr)
                last = time.time()
            else:
                sleep(1)

        except pexpect.TIMEOUT as e:
            if time.time() - first > tmout:
                print('\nTimeout of %d seconds exceeded, giving up.' % tmout, file=sys.stderr)
                exit(1)
            elif time.time() - last > cycle:
                print('\nCycle timeout of %d seconds exceeded, sending CR.' % cycle, file=sys.stderr)
                child.send("\r")

        except:
            print('Exception: %s' % sys.exc_info()[0], file=sys.stderr)
            exit(1)

if __name__ == "__main__":
    main(sys.argv[1:])

