const sources = [
  "js/releasable-observer.js",
  "js/pcg-base.js",
  "js/pcg-dom-util.js",

  "js/helpers/rand.js",

  "js/model/store.js",
  "js/model/data.js",

  "js/model/provider.js",
  "js/model/slice/productTable.js",

  "js/model/tag.js",
  "js/model/product.js",

  "js/helpers/textFilter.js",
  "js/helpers/answer.js",

  "js/controller/quizBits/main.js",

  "js/controller/quizGenerator.js",
  "js/controller/quizBits/checkbox.js",
  "js/controller/quizBits/checkboxPhoto.js",
  "js/controller/quizBits/radio.js",
  "js/controller/quizBits/radioPhoto.js"
];
const fs = require('fs'),
  path = require('path');
var js = sources.map(a=>path.join(__dirname,'../../public',a)).map(n=>fs.readFileSync(n)+'').join('\n\n');


const data = require("../../db.js");
const body = 'const window = {}, localStorage = {getItem:()=>"{}"};'+js+'; return {quizGenerator, standardGenerator, initDataProvider, seeded: Math.random.seeded, rand}';


var ctx = new Function('',body)();

const rand = ctx.rand,
  seeded = ctx.seeded;

data.after = function(inComeData, skipInit){
  if( inComeData ){
    ctx.initDataProvider( data );
    countStdQ = Object.values(data.standardQuestions).length;
  }
};

let countStdQ;
module.exports = {
  '/api/generate/random': {
    method: 'GET',
    summary: 'Generate random quiz',
    options:{
      seed: {required: false, description: 'initialize random state. Make response determined', type: String},
      photo: {required: false, description: 'question with photo', type: Boolean},
      type: {required: false, description: '1 - products, 2 - standards', type: Number},
      nolog: {required: false, description: 'remove human readable log', type: Boolean}
    },
    fn: async function(args) {
      let seed = args.seed || Math.random().toString(36).substr(2);
      ctx.seeded.setStringSeed( seed );

      let multiple = seeded() > 24 / ( 46 + 24 ),
          photo = seeded() > 0.7,
          result;

      while(!result){
        if( ( args.type !== void 0 ? args.type === 2 : seeded() > 0.5 ) ){
          result = ctx.standardGenerator( () => rand( 1, countStdQ ) )
        }else{
          result = ctx.quizGenerator( multiple ? 'checkbox' : 'radio', args.photo !== void 0 ? args.photo : photo );
        }
      }

      console.log(`cat: ${result.categoryId}, prod: ${result.productId}, seed: ${seed}. ${result.question.substr(0,33)}`);

      if(args.nolog)
        delete result.log;

      return result;
    }
  },
  '/api/generate/random/sequence': {
    method: 'GET',
    summary: 'Generate list of random quizes',
    options:{
      count: {required: true, description: 'Count of generated questions', type: Number},
      seed: {required: false, description: 'initialize random state. Make response determined', type: String},
      photo: {required: false, description: 'question with photo', type: Boolean},
      type: {required: false, description: '1 - products, 2 - standards', type: Number},
      nolog: {required: false, description: 'remove human readable log', type: Boolean}
    },
    fn: async function(args) {
      let seed = args.seed || Math.random().toString(36).substr(2);
      ctx.seeded.setStringSeed( seed );
      let used = {}, generated = 0;
      let last = {c:-1},
        list = [],
        globalMaxTries = args.count*100,
        globalTries = 0;
      while(generated<args.count && globalTries < globalMaxTries){
        globalTries++;
        let cur = {
          m: seeded() > 24 / ( 46 + 24 ),
          p: seeded() > 0.7,
          c: 1
        };
        if( last.c === 1 && seeded() > 0.5 ){
          cur = {
            c: 2
          };
          let id, tries = 0;
          do{
            id = rand(1, countStdQ);
            tries++;
            if(tries === 100){
              break;
            }
          }while('2.'+id in used);
          if(tries===100)
            continue;
          cur.id = id;
        }

        let tries = 0,
          result;
        do{
          if(cur.c === 1){
            result = ctx.quizGenerator( cur.m ? 'checkbox' : 'radio', cur.p );
          }else{

            result = ctx.standardGenerator(()=>cur.id)
            if(!result){
              tries = 100;
              break;
            }
          }
          tries++;
          if(tries === 100)
            break;

        }while(result.categoryId+'.'+result.productId in used);
        if(tries !== 100){

          used[result.categoryId+'.'+result.productId] = true;
          list.push(result);
          if(args.nolog)
            delete result.log;
          last = cur;
          generated++;
          result.number = generated;
        }
      }
      return list;
    }
  }
};