/*
 * Copyright 2016 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef wasm_learning_h
#define wasm_learning_h

#include <algorithm>
#include <random>

namespace wasm {

//
// Machine learning using a genetic algorithm.
//
// The Genome class is the element on which to learn. It must
// implement the following:
//
//  * Fitness getFitness(); - calculate how good this item is.
//
// The Generator must implement the following:
//
//  * Genome* makeRandom(); - make a random element
//  * Genome* makeMixture(Genome* one, Genome* two); - make a new element by mixing two
//
// Fitness is the type of the fitness values, e.g. uint32_t. More is better.
//
// Typical usage of this class is to run call runGeneration(), check the best
// quality using getBest()->getFitness(), and do that repeatedly until the
// fitness is good enough. Then acquireBest() to get ownership of the best,
// and the learner can be discarded (with all the rest of the population
// cleaned up).

template<typename Genome, typename Fitness, typename Generator>
class GeneticLearner {
  Generator& generator;

  typedef std::unique_ptr<Genome> unique_ptr;
  std::vector<unique_ptr> population;

  void sort() {
    std::sort(population.begin(), population.end(), [this](const unique_ptr& left, const unique_ptr& right) {
      return left->getFitness() > right->getFitness();
    });
  }

  std::mt19937 noise;

  size_t randomIndex() {
    return noise() % population.size();
  }

public:
  GeneticLearner(Generator& generator, size_t size) : generator(generator), noise(1337) {
    population.resize(size);
    for (size_t i = 0; i < size; i++) {
      population[i] = unique_ptr(generator.makeRandom());
    }
    sort();
  }

  Genome* getBest() {
    return population[0].get();
  }

  unique_ptr acquireBest() {
    return population[0];
  }

  void runGeneration() {
    size_t size = population.size();

    // we have a mix of promoted from the last generation, mixed from the last generation, and random
    const size_t promoted = (25 * size) / 100;
    const size_t mixed = (50 * size) / 100;

    // promoted just stay in place
    // mixtures are computed, then added back in (as we still need them as we work)
    std::vector<unique_ptr> mixtures;
    mixtures.resize(mixed);
    for (size_t i = 0; i < mixed; i++) {
      mixtures[i] = unique_ptr(generator.makeMixture(population[randomIndex()].get(), population[randomIndex()].get()));
    }
    for (size_t i = 0; i < mixed; i++) {
      population[promoted + i].swap(mixtures[i]);
    }
    // TODO: de-duplicate at this point
    // randoms fill in the test
    for (size_t i = promoted + mixed; i < size; i++) {
      population[i] = unique_ptr(generator.makeRandom());
    }

    sort();
  }
};

}  // namespace wasm

#endif  // wasm_learning_h

