# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import gobject, os

from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib.cros import policy, session_manager
from autotest_lib.client.cros import cros_ui, cryptohome, ownership

from dbus.mainloop.glib import DBusGMainLoop

class login_MultipleSessions(test.test):
    """Ensure that the session_manager can handle multiple calls to StartSession
       correctly.
    """
    version = 1

    def setup(self):
        os.chdir(self.srcdir)
        utils.make('OUT_DIR=.')


    def initialize(self):
        super(login_MultipleSessions, self).initialize()
        # Ensure a clean beginning.
        cros_ui.stop()
        ownership.clear_ownership_files()
        cros_ui.start()

        DBusGMainLoop(set_as_default=True)
        self._session_manager = session_manager.connect()
        self._listener = session_manager.SignalListener(gobject.MainLoop())
        self._listener.listen_for_new_key_and_policy()


    def run_once(self):
        expected_owner = 'first_user@nowhere.com'
        other_user = 'second_user@nowhere.com'
        self.__start_session_for(expected_owner)
        self.__start_session_for(other_user)

        self._listener.wait_for_signals(desc='Initial policy push complete.')

        # Ensure that the first user got to be the owner.
        retrieved_policy = policy.get_policy(self._session_manager)
        if retrieved_policy is None: raise error.TestFail('Policy not found')
        policy.compare_policy_response(self.srcdir, retrieved_policy,
                                       owner=expected_owner)

        # bounce the session manager and wait for it to come back up before
        # reconnecting.
        cros_ui.restart()
        self._session_manager = session_manager.connect()

        # Destroy the owner's cryptohome and start sessions again in a
        # different order
        self.__start_session_for(other_user)
        self.__start_session_for(expected_owner)

        self._listener.wait_for_signals(desc='Re-taking of ownership complete.')

        # Ensure that the first user still gets to be the owner.
        retrieved_policy = policy.get_policy(self._session_manager)
        if retrieved_policy is None: raise error.TestFail('Policy not found')
        policy.compare_policy_response(self.srcdir, retrieved_policy,
                                       owner=expected_owner)


    def __start_session_for(self, user):
        """Call StartSession() for user, ensure he has clean on-device state

        Make a fresh cryptohome for user, and then start a session for him
        with the session manager.

        @param user: the user to start a session for.

        @raises error.TestFail: if the session cannot be started.
        """
        cryptohome.ensure_clean_cryptohome_for(user)
        if not self._session_manager.StartSession(user, ''):
            raise error.TestFail('Could not start session for ' + user)


    def cleanup(self):
        cros_ui.start(allow_fail=True, wait_for_login_prompt=False)
