// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
 * smart-service provides an asynchronous interface for machine learning.
 * Hooks to this service should make updates and ask for predictions.
 * A few basic learners are implemented as wrappers around the learning library.
 */

var addAttributes = require('../../lib/addAttributes');
var store = require('../../lib/store');
var log = require('../../lib/log')('services:smart-service');
var constants = require('./service-implementation');
var extendDefaults = require('../../lib/extend-defaults');

// Export methods and constants
module.exports = {
  loadOrCreate: loadOrCreate,
  reset: reset,
  save: save,
  update: update,
  predict: predict,
  constants: constants
};

// This caches the learners loaded into memory.
var learners = {};

/*
 * Given an id, type, and parameters, return a promise that attempts to load the
 * learner from the store, and failing that, creates a new one.
 *
 * Registers and resolves the learner upon success.
 * Rejects when the id is taken, or the type is invalid.
 */
function loadOrCreate(id, type, params) {
  log.debug('load or create', id, type, params);

  if (learners[id] !== undefined) {
    return Promise.reject('Cannot reuse learner id ' + id);
  }

  // Store the learner right away. Calls to get should use this promise.
  learners[id] = load(id).then(function loadSuccess(learner) {
    log.debug('loaded learner', id);
    learner.params = extendDefaults(learner.params, params);
    return Promise.resolve(learner);
  }, function loadFailure() {
    return create(id, type, params).then(function(learner) {
      log.debug('created learner', id);
      return Promise.resolve(learner);
    });
  }).catch(function(err) {
    log.error('Unable to load or create', id, err);
    return Promise.reject(err);
  });

  return learners[id];
}

/*
 * Return a promise containing the learner at the given id. The promise rejects
 * if that learner has not been registered yet.
 */
function get(id) {
  if (learners[id] === undefined) {
    return Promise.reject('Unused learner id ' + id);
  }
  return learners[id];
}

/*
 * Return a promise to delete from the store and in-memory buffer.
 */
function reset(id) {
  log.debug('reset', id);
  return store.removeValue(id).then(function() {
    if (learners[id] === undefined) {
      return Promise.reject('Cannot reset unused learner id ' + id);
    }
    delete learners[id];
  }).catch(function(err) {
    log.error('Failed to reset learner id:', id, err);
    return Promise.reject(err);
  });
}

/*
 * Given an id, return a promise that saves the learner to the store.
 */
function save(id) {
  if (learners[id] === undefined) {
    return Promise.reject('Cannot save unused learner id ' + id);
  }
  return learners[id].then(function(learner) {
    return store.setValue(id, learner);
  }).catch(function(err) {
    log.error('Unable to save learner', err);
    return Promise.reject(err);
  });
}

/*
 * Given an id and input, return a promise to update the corresponding learner
 * with that input and save to the store.
 */
function update(id, input) {
  return get(id).then(function(learner) {
    learner.update(input);

    return save(id);
  });
}

/*
 * Given an id and input, return a promise that uses the corresponding learner
 * to make a prediction on the input.
 */
function predict(id, input) {
  return get(id).then(function(learner) {
    return learner.predict(input);
  });
}

/*
 * Helper function; returns a promise to create a new learner.
 */
function create(id, type, params) {
  log.debug('create', id, type, params);
  if (constants.LEARNER_MAP[type] === undefined) {
    return Promise.reject('Could not resolve learner type ' + type);
  } else {
    var LearnerConstructor = constants.LEARNER_MAP[type];
    var learner = new LearnerConstructor(type, params);
    return Promise.resolve(learner);
  }
}

/*
 * Helper function; returns a promise that loads a new learner from the store.
 * Rejects if the value is null.
 */
function load(id) {
  log.debug('load', id);
  return store.getValue(id).then(function(learner) {
    if (learner === null) {
      return Promise.reject('Learner ' + id + ' was not present in the store.');
    } else {
      log.debug('Loaded Learner:', learner);

      // Attach the learner's functions, then resolve.
      addAttributes(learner, constants.LEARNER_METHODS[learner.type]);
      return Promise.resolve(learner);
    }
  });
}