#!/usr/bin/python

import sys
import time
import os
import pwd
import subprocess
import shutil
import argparse

from stat import ST_MODE
from xpresser import Xpresser
from xpresser import ImageNotFound


def user_exists(user):
    ''' Make sure that the given user exists on the system '''
    try:
        user_info = pwd.getpwnam(user)
        print("User %s found with UID %s" % (user, user_info.pw_uid))
        return True
    except KeyError:
        print("User %s not found or removed" % user)
        return False


def home_dir_exists(user):
    ''' Checks for a directory in /home/user where user is given '''
    home_dir = pwd.getpwnam(user).pw_dir
    try:
        if os.path.isdir(home_dir):
            print("Home directory for %s found" % user)
            assert(_check_dir_permissions(home_dir) == '755')
            return True
        else:
            sys.stderr.write("No home directory for %s found" % user)
            return False
    except AssertionError:
        sys.stderr.write("Permissions not set properly to 755")
        return False


def _check_dir_permissions(dir):
    ''' Checks the permissions of the given directory '''
    mode = oct(os.stat(dir)[ST_MODE])[-3:]
    return mode


def cleanup_user(user):
    ''' Will delete the given user, and delete the user's home directory '''
    success = True
    print("Deleting user %s" % user)
    try:
        output = subprocess.Popen(['deluser', '--remove-home', user],
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        time.sleep(1)
        output.poll()
        if output.returncode == 0 and not user_exists(user):
            print("User %s has been removed" % user)
        else:
            error_output = output.stderr.read()
            sys.stderr.write("Deleting user %s has failed with error: %s"
                 % (user, error_output))
            success = False
    except Exception as e:
        print("Failure during cleanup: %s" % e)
        success = False
    return success


def run_oem_config(user, passw, images_dir):
    ''' Call and run through oem-config using xpresser '''
    oem_config_de = subprocess.check_output(['oem-config', '-q'])
    if 'gtk_ui' not in oem_config_de:
        print("OEM-config is using %s, only gtk is supported" % oem_config_de)
    else:
        subprocess.Popen(['oem-config'])
        time.sleep(5)
        xp.find('welcome')
        try:
            xp.find('english_checked')
            print("English  selected, clicking continue")
        except ImageNotFound:
            xp.click('english_unchecked')
            print("English already selected, clicking continue")
        finally:
            xp.click('continue_button')
        try:
            xp.wait('wireless')
            print("Wireless screen found, skipping")
            xp.click('continue_button')
        except ImageNotFound:
            print("Wireless screen not found, no WLAN setup")
        xp.wait('where_are_you')
        print("Timezone screen found. Leaving default, clicking continue")
        xp.click('continue_button')
        xp.wait('keyboard_layout')
        print("Keyboard screen found, leaving default. Clicking continue")
        xp.click('continue_button')
        xp.wait('who_are_you')
        print(("User creation screen found.  Adding user %s with password %s"
                % (user, passw)))
        print("Editing 'your name' field")
        time.sleep(1)
        xp.type(user)
        time.sleep(1)
        print("Editing password field")
        xp.click('password')
        xp.type(passw)
        time.sleep(.5)
        print("Retyping password")
        xp.click('password2')
        xp.type(passw)
        print('Done editing, clicking continue')
        xp.click('continue_button')
        print('OEM config user setup completed')
        try:
            xp.find('choose_your_picture')
            print("Picture screen found, clicking continue")
            xp.click('continue_button')
        except:
            print("No picture screen found")


def is_oem_config_done(timeout):
    ''' Loops through every 15 seconds to see if oem-config is done '''
    is_done = False
    how_long = 0
    while (not is_done):
        try:
            xp.find('not_done', 5)
            print("OEM config still running")
            how_long += 5
            if how_long > timeout:
                sys.stderr.write('OEM config timeout exceeded.')
                sys.exit(1)
            time.sleep(5)
        except ImageNotFound:
            if how_long == 0:
                sys.stderr.write('OEM config not found to be running')
                sys.exit(1)
            else:
                print("OEM config completed!  Took %i seconds" % how_long)
                is_done = True
    return is_done


if __name__ == "__main__":
    p = argparse.ArgumentParser(description="Automatically tests oem-config")
    p.add_argument('-u', '--user', dest='user', required=True,
                  help='User to create')
    p.add_argument('-p', '--password', dest='passw',
                  required=True, help='Password to create')
    p.add_argument('-d', '--image-dir', dest='images_dir', required=True,
                  help='Directory where the oem-config Xpresser images live')
    p.add_argument('-t', '--timeout', dest='timeout', type=int, default=120,
                  help='Timeout before oem-config is considered failed in '
                  'seconds. Default is 120')
    args = p.parse_args()
    xp = Xpresser()
    xp.load_images(args.images_dir)
    run_oem_config(args.user, args.passw, args.images_dir)
    if not is_oem_config_done(args.timeout):
        sys.exit(1)
    if not user_exists(args.user):
        sys.exit(1)
    if not home_dir_exists(args.user):
        sys.exit(1)
    time.sleep(1)
    if not cleanup_user(args.user):
        sys.exit(1)
