import {call, put, take, select, takeEvery} from 'redux-saga/effects';
import {fetchTaskData, gradeAnswer} from './server_module';

import PlatformChannel from './platform_channel';

export default function (bundle, deps) {


    bundle.use('taskInit', 'taskRefresh');



    bundle.defineAction('taskData', 'taskData');
    bundle.addReducer('taskData', function (state, action) {
        const {task} = action;
        return {...state, task};
    });


    bundle.defineAction('taskToken', 'taskToken');
    bundle.addReducer('taskToken', function (state, action) {
        const {task_token} = action;
        return {...state, task_token};
    });


    bundle.defineAction('reloadState', 'reloadState');
    bundle.addReducer('reloadState', function (state, action) {
        const {hints} = action;
        return {...state, hints};
    });


    bundle.defineAction('reloadAnswer', 'reloadAnswer');
    bundle.addReducer('reloadAnswer', function (state, action) {
        const answer = action.answer;
        return {...state, answer};
    });







    bundle.addSaga(function* () {
        /* TODO: select task from global state */
        const channel = yield call(PlatformChannel, window.task);
        yield takeEvery(channel, handlePlatformEventSaga);
    });

    function* handlePlatformEventSaga (event) {
        let callback = event.callback || function (){};
        switch(event.type) {
            case 'load':
                const task_token = yield select(state => state.task_token);
                const host = yield select(state => state.options.server_module.host);
                const task = yield call(fetchTaskData, host, task_token);
                yield put({type: deps.taskData, task});
                yield put({type: deps.taskInit});
                callback();
                break;

            case 'getState':
                const hints = yield select(state => state.hints);
                console.log('getState', JSON.stringify(hints));
                callback(JSON.stringify(hints));
                break;

            case 'reloadState':
                console.log('reloadState', event.state);
                try {
                    const hints = JSON.parse(event.state);
                    yield put({type: deps.reloadState, hints});
                    yield put({type: deps.taskRefresh});
                } catch(e) {
                    console.error(e.message, 'reloadState wrong JSON');
                }
                callback();
                break;

            case 'getAnswer':
                const answer = yield select(state => state.answer);
                console.log('getAnswer', JSON.stringify(answer));
                callback(JSON.stringify(answer));
                break;

            case 'reloadAnswer':
                console.log('reloadAnswer');
                try {
                    const answer = JSON.parse(event.answer);
                    yield put({type: deps.reloadAnswer, answer});
                    yield put({type: deps.taskRefresh});
                } catch(e) {
                    console.error(e.message, 'reloadAnswer wrong JSON');
                }
                callback();
                break;

            case 'gradeAnswer':
                const host = yield select(state => state.options.server_module.host);
                const task_token = yield select(state => state.task_token);
                const task_params = yield call(getTaskParams);
                const grading = yield call(gradeAnswer, host, task_token, event.answer_token, task_params);
                alert('Score: ' + grading.score);
                break;
        }
    }
}


function getTaskParams () {
    return new Promise(resolve => {
        platform.getTaskParams(null, null, resolve);
    });
}
@@ -1783,32 +1783,43 @@
             
+yield call(
 callback
 ();%0A        
@@ -1798,33 +1798,32 @@
 ld call(callback
-(
 );%0A             
@@ -2004,32 +2004,43 @@
             
+yield call(
 callback
 (JSON.string
@@ -2019,33 +2019,34 @@
 ld call(callback
-(
+, 
 JSON.stringify(h
@@ -2499,32 +2499,43 @@
             
+yield call(
 callback
 ();%0A        
@@ -2514,33 +2514,32 @@
 ld call(callback
-(
 );%0A             
@@ -2729,24 +2729,35 @@
         
+yield call(
 callback
 (JSON.st
@@ -2748,17 +2748,18 @@
 callback
-(
+, 
 JSON.str
@@ -3219,24 +3219,35 @@
         
+yield call(
 callback
 ();%0A    
@@ -3238,17 +3238,16 @@
 callback
-(
 );%0A     
@@ -3514,32 +3514,32 @@
 getTaskParams);%0A
-
                 
@@ -3622,32 +3622,101 @@
 , task_params);%0A
+                /* XXX do something and eventually call callback? */%0A
                 

use call effect to invoke foreign code from inside a saga