/*
 *  Copyright (C) 2016-2019 Savoir-faire Linux Inc.
 *
 *  Author: Romain Bertozzi <romain.bertozzi@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */

import XCTest
@testable import Ring

/**
 A test class designed to validate that the daemon service runs as expected.
 It will test for example that:
 - the daemon correctly starts
 - correctly stops
 - fails to achieve one or the other as we expect it to do.
 */
class DaemonServiceTests: XCTestCase {
    /**
     Tests that the Ring Daemon Service starts the daemon correctly

     - Returns: the DaemonService used to do the test
     */
    func testStart() -> DaemonService {
        var hasStartError = false
        let daemonService = DaemonService.init(dRingAdaptor: DRingAdapter())
        do {
            try daemonService.startDaemon()
        } catch {
            hasStartError = true
        }
        XCTAssertFalse(hasStartError)
        XCTAssertTrue(daemonService.daemonStarted)
        return daemonService
    }

    /**
     Tests that the Ring Daemon Service stops the daemon correctly

     - Returns: the DaemonService used to do the test
     */
    func testStop() -> DaemonService {
        var hasStopError = false
        let daemonService = testStart()
        do {
            try daemonService.stopDaemon()
        } catch {
            hasStopError = true
        }
        XCTAssertFalse(hasStopError)
        XCTAssertFalse(daemonService.daemonStarted)
        return daemonService
    }

    /**
     Tests that the Ring Daemon Service does not start again if it is already started.
     */
    func testAlreadyRunningException() {
        let daemonService = testStart()
        XCTAssertThrowsError(try daemonService.startDaemon()) { (error) in
            XCTAssertEqual(error as? StartDaemonError, StartDaemonError.daemonAlreadyRunning)
        }
    }

    /**
     Tests that the Ring Daemon Service does not stop if it is not currently running.
     */
    func testDaemonNotRunningException() {
        let daemonService = DaemonService.init(dRingAdaptor: DRingAdapter())
        XCTAssertThrowsError(try daemonService.stopDaemon()) { (error) in
            XCTAssertEqual(error as? StopDaemonError, StopDaemonError.daemonNotRunning)
        }
    }

    /**
     Tests that the Ring Daemon Service fails to initialize.
     This test use a dedicated DRingAdaptor fixture.
     */
    func testDaemonFailToInit() {
        let daemonService = DaemonService.init(dRingAdaptor: FixtureFailInitDRingAdapter())
        XCTAssertThrowsError(try daemonService.startDaemon()) { (error) in
            XCTAssertEqual(error as? StartDaemonError, StartDaemonError.initializationFailure)
        }
    }

    /**
     Tests that the Ring Daemon Service fails to start.
     This test use a dedicated DRingAdaptor fixture.
     */
    func testDaemonFailToStart() {
        let daemonService = DaemonService.init(dRingAdaptor: FixtureFailStartDRingAdapter())
        XCTAssertThrowsError(try daemonService.startDaemon()) { (error) in
            XCTAssertEqual(error as? StartDaemonError, StartDaemonError.startFailure)
        }
    }
}
