import {
	call,
	put,
	select,
	takeLatest,
	race
} from 'redux-saga/effects'
import { delay } from 'redux-saga'
import moment from 'moment'
import ssoService from '../services/ssoService'
import { SSO_TTL } from '../AppSettings'
import logger from '../util/logger'

const auth = require('../util/auth')

const getUserData = state => (state.user)

function* doLogin(action) {
	const {
		username,
		password,
	} = action

	yield put({ type: 'LOG_IN_REQUEST' })
	try {
		if (!password || password.length === 0) {
			const e = new Error('Please type in your password.')
			e.name = 'emptyPasswordError'
			yield call(delay, 0)
			throw e
		}
		const passwordEncrypted = yield auth.encryptStringWithKey(password)
		const loginInfo = auth.encryptStringWithBase64(`${username}:${passwordEncrypted}`)

		const { response, timeout } = yield race({
			response: call(ssoService.retrieveAccessToken, loginInfo),
			timeout: call(delay, SSO_TTL)
		})

		if (timeout) {
			const e = new Error('Logging in timed out.')
			e.name = 'ssoTimeout'
			throw e
		} else if (response.error) {
			logger.log(response)
			throw response.error
		} else {
			// Successfully logged in
			yield auth.storeUserCreds(username, password)
			yield auth.storeAccessToken(response.access_token)

			// Set up user profile
			const newProfile = {
				username,
				pid: response.pid,
				classifications: { student: Boolean(response.pid) }
			}

			yield put({ type: 'LOGGED_IN', profile: newProfile, expiration: response.expiration })
			yield put({ type: 'LOG_IN_SUCCESS' })
			yield put({ type: 'TOGGLE_AUTHENTICATED_CARDS' })
		}
	} catch (error) {
		logger.log(error)
<<<<<<< HEAD
		yield put({
			type: 'USER_LOGIN_FAILED',
			error: error.message
		})
=======
		yield put({ type: 'LOG_IN_FAILURE', error })
>>>>>>> d760234e7a75c15b880ad2d218a027411fe5ec67
	}
}

function* doTokenRefresh() {
	const { expiration } = yield select(getUserData)

	// Check if expiration time is past current time
	if (moment().isAfter(moment.unix(expiration))) {
		// Get username and password from keystore
		const {
			username,
			password
		} = yield auth.retrieveUserCreds()

		yield put({
			type: 'USER_LOGIN',
			username,
			password
		})
	}
}

function* doLogout(action) {
	yield auth.destroyUserCreds()
	yield auth.destroyAccessToken()
	yield put({ type: 'LOGGED_OUT' })
	yield put({ type: 'TOGGLE_AUTHENTICATED_CARDS' })
}

<<<<<<< HEAD
function* timeoutError() {
	const error = new Error('There was a problem signing in. Please try again later.')
	yield put({
		type: 'USER_LOGIN_FAILED',
		error: error.message
	})
}

function* clearErrors(action) {
	yield put({
		type: 'USER_SET_ERRORS',
		error: null
	})
}

=======
>>>>>>> d760234e7a75c15b880ad2d218a027411fe5ec67
function* userSaga() {
	yield takeLatest('USER_LOGIN', doLogin)
	yield takeLatest('USER_LOGOUT', doLogout)
	yield takeLatest('USER_TOKEN_REFRESH', doTokenRefresh)
}

export default userSaga

@@ -1639,197 +1639,54 @@
 or)%0A
-%3C%3C%3C%3C%3C%3C%3C HEAD%0A%09%09yield put(%7B%0A%09%09%09type: 'USER_LOGIN_FAILED',%0A%09%09%09error: error.message%0A%09%09%7D)%0A=======%0A%09%09yield put(%7B type: 'LOG_IN_FAILURE', error %7D)%0A%3E%3E%3E%3E%3E%3E%3E d760234e7a75c15b880ad2d218a027411fe5ec67
+%09%09yield put(%7B type: 'LOG_IN_FAILURE', error %7D)
 %0A%09%7D%0A
@@ -2245,354 +2245,8 @@
 %0A%7D%0A%0A
-%3C%3C%3C%3C%3C%3C%3C HEAD%0Afunction* timeoutError() %7B%0A%09const error = new Error('There was a problem signing in. Please try again later.')%0A%09yield put(%7B%0A%09%09type: 'USER_LOGIN_FAILED',%0A%09%09error: error.message%0A%09%7D)%0A%7D%0A%0Afunction* clearErrors(action) %7B%0A%09yield put(%7B%0A%09%09type: 'USER_SET_ERRORS',%0A%09%09error: null%0A%09%7D)%0A%7D%0A%0A=======%0A%3E%3E%3E%3E%3E%3E%3E d760234e7a75c15b880ad2d218a027411fe5ec67%0A
 func

Resolve merge conflict