
var basal = require('./basal');
var targets = require('./targets');
var isf = require('./isf');
var carb_ratios = require('./carbs');
var _ = require('lodash');

function defaults ( ) {
  var profile = {
    max_iob: 0 // if max_iob is not provided, never give more insulin than the pump would have
   // , type: 'current'
    , max_daily_safety_multiplier: 3
    , current_basal_safety_multiplier: 4
    , autosens_max: 1.2
    , autosens_min: 0.7
    , rewind_resets_autosens: false // reset autosensitivity to neutral for awhile after each pump rewind
    , autosens_adjust_targets: true // when autosens detects sensitivity/resistance, also adjust BG target accordingly
    , adv_target_adjustments: false // lower target automatically when BG and eventualBG are high
    // create maxCOB and default it to 120 because that's the most a typical body can absorb over 4 hours.
    // (If someone enters more carbs or stacks more; OpenAPS will just truncate dosing based on 120.
    // Essentially, this just limits AMA as a safety cap against weird COB calculations)
    , maxCOB: 120
    , override_high_target_with_low: false // allows a much higher target used only for avoiding bolus wizard overcorrections
    , skip_neutral_temps: false // if true, don't set neutral temps
    , bolussnooze_dia_divisor: 2 // bolus snooze decays after 1/2 of DIA
    , min_5m_carbimpact: 3 // mg/dL per 5m
    , carbratio_adjustmentratio: 1 // if carb ratios on pump are set higher to lower initial bolus using wizard, .8 = assume only 80 percent of carbs covered with full bolus
    , autotune_isf_adjustmentFraction: 0.5 // keep autotune ISF closer to pump ISF via a weighted average of fullNewISF and pumpISF.  1.0 allows full adjustment, 0 is no adjustment from pump ISF.
    // if anyone wants to set remainingCarbsFraction in preferences.json, uncomment this
    //, remainingCarbsFraction: 0.67 // fraction of carbs we'll assume will absorb over 4h if we don't yet see carb absorption
    , remainingCarbsCap: 0 // max carbs we'll assume will absorb over 4h if we don't yet see carb absorption
    // WARNING: the following are advanced oref1 features, and are not yet tested for general use
    , enableUAM: false // enable detection of unannounced meal carb absorption
    , enableSMB_with_bolus: false // enable supermicrobolus for DIA hours after a manual bolus
    , enableSMB_with_COB: false // enable supermicrobolus while COB is positive
    , enableSMB_with_temptarget: false // enable supermicrobolus for eating soon temp targets
  };
  return profile;
}

function generate (inputs, opts) {
  var profile = opts && opts.type ? opts : defaults( );

  // check if inputs has overrides for any of the default prefs
  // and apply if applicable
  for (var pref in profile) {
    if (inputs.hasOwnProperty(pref)) {
      profile[pref] = inputs[pref];
    }
  }

  var pumpsettings_data = inputs.settings;
  if (inputs.settings.insulin_action_curve > 1) {
    profile.dia =  pumpsettings_data.insulin_action_curve;
  } else {
    console.error('DIA of', profile.dia, 'is not supported');
    return -1;
  }

  if (inputs.model) {
    profile.model = inputs.model;
  }
  profile.skip_neutral_temps = inputs.skip_neutral_temps;

  profile.current_basal = basal.basalLookup(inputs.basals);
  profile.basalprofile = inputs.basals;
  
  _.forEach(profile.basalprofile, function(basalentry) {
    basalentry.rate = +(Math.round(basalentry.rate + "e+3")  + "e-3");		
  });
  
  profile.max_daily_basal = basal.maxDailyBasal(inputs);
  profile.max_basal = basal.maxBasalLookup(inputs);
  if (profile.current_basal === 0) {
    console.error("current_basal of",profile.current_basal,"is not supported");
    return -1;
  }
  if (profile.max_daily_basal === 0) {
    console.error("max_daily_basal of",profile.max_daily_basal,"is not supported");
    return -1;
  }
  if (profile.max_basal < 0.1) {
    console.error("max_basal of",profile.max_basal,"is not supported");
    return -1;
  }

  var range = targets.bgTargetsLookup(inputs, profile);
  profile.out_units = inputs.targets.user_preferred_units;
  profile.min_bg = Math.round(range.min_bg);
  profile.max_bg = Math.round(range.max_bg);
  profile.bg_targets = inputs.targets;
  
  _.forEach(profile.bg_targets.targets, function(bg_entry) {
    bg_entry.high = Math.round(bg_entry.high);
    bg_entry.low = Math.round(bg_entry.low);
    bg_entry.min_bg = Math.round(bg_entry.min_bg);
    bg_entry.max_bg = Math.round(bg_entry.max_bg);
  });
  
  delete profile.bg_targets.raw;
  
  profile.temptargetSet = range.temptargetSet;
  profile.sens = isf.isfLookup(inputs.isf);
  profile.isfProfile = inputs.isf;
  if (profile.sens < 5) {
    console.error("ISF of",profile.sens,"is not supported");
    return -1;
  }
  if (typeof(inputs.carbratio) != "undefined") {
    profile.carb_ratio = carb_ratios.carbRatioLookup(inputs, profile);
    profile.carb_ratios = inputs.carbratio;
  } else {
    console.error("Profile wasn't given carb ratio data, cannot calculate carb_ratio");
  }

  return profile;
}


generate.defaults = defaults;
exports = module.exports = generate;


@@ -1373,17 +1373,17 @@
 impact: 
-3
+5
  // mg/d
@@ -1390,16 +1390,62 @@
 L per 5m
+ (corresponds to 15g/hr at a CSF of 4 mg/dL/g)
 %0A    , c

increase default min_5m_carbimpact to help avoid overestimating COB