import { ActionsObservable } from 'redux-observable';
import { writeFileObservable } from '../../utils/fs';

const Rx = require('rxjs/Rx');
const commutable = require('commutable');

const Observable = Rx.Observable;

export const SAVE = 'SAVE';
export const SAVE_AS = 'SAVE_AS';
export const CHANGE_FILENAME = 'CHANGE_FILENAME';
export const DONE_SAVING = 'DONE_SAVING';

export const changeFilename = filename => ({ type: CHANGE_FILENAME, filename });
export const save = (filename, notebook) => ({ type: SAVE, filename, notebook });
export const saveAs = (filename, notebook) => ({ type: SAVE_AS, filename, notebook });
export const doneSaving = () => ({ type: DONE_SAVING });

export function saveEpic(action$) {
  return action$.ofType(SAVE)
    .do(action => {
      // If there isn't a filename, save-as it instead
      if (!action.filename) {
        throw new Error('save needs a filename');
      }
    })
    .mergeMap(action =>
      writeFileObservable(action.filename,
        JSON.stringify(
          commutable.toJS(
            action.notebook.update('cellMap', (cells) =>
              cells.map((value) =>
                value.delete('inputHidden').delete('outputHidden').delete('status')))),
          null,
          1))
        .catch(error => {
          const input$ = Observable.of({ type: 'SAVING_ERROR' });
          return new ActionsObservable(input$);
        })
        .map(doneSaving)
        // .startWith({ type: START_SAVING })
        // since SAVE effectively acts as the same as START_SAVING
        // you could just look for that in your reducers instead of START_SAVING
    );
}

export function saveAsEpic(actions) {
  return actions.ofType(SAVE_AS)
    .mergeMap(action => [
      changeFilename(action.filename),
      save(action.filename, action.notebook),
    ]);
}

@@ -1307,32 +1307,13 @@
 .of(
-%7B type: 'SAVING_ERROR' %7D
+error
 );%0A 

Change observable on error.