package org.mitre.synthea.modules;

import static org.junit.Assert.assertEquals;

import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mitre.synthea.helpers.Utilities;
import org.mitre.synthea.world.agents.Person;

public class LifecycleModuleTest {
  public static boolean deathByNaturalCauses;
  
  @BeforeClass
  public static void before() {
    deathByNaturalCauses = LifecycleModule.ENABLE_DEATH_BY_NATURAL_CAUSES;
  }

  @AfterClass
  public static void after() {
    LifecycleModule.ENABLE_DEATH_BY_NATURAL_CAUSES = deathByNaturalCauses;
  }

  @Test
  public void testDeathByNaturalCauses() {
    LifecycleModule.ENABLE_DEATH_BY_NATURAL_CAUSES = true;
    Person person = new Person(0L);
    long time = System.currentTimeMillis();
    long birth = time - Utilities.convertTime("years", 100);
    person.attributes.put(Person.BIRTHDATE, birth);
    for (int i = 0; i < 100000; i++) {
      LifecycleModule.death(person, time);
    }
    assertEquals(false, person.alive(time));
  }

  @Test
  public void testLikelihoodOfDeathInputs() {
    // should handle zero to very old
    for (int age = 0; age < 100; age++) {
      double likelihood = LifecycleModule.likelihoodOfDeath(age);
      Assert.assertTrue(likelihood >= 0);
    }
  }

  @Test
  public void testAdherenceFade() {
    Person person = new Person(0L);
    long time = System.currentTimeMillis();
    person.attributes.put(Person.ADHERENCE, true);
    person.attributes.put(LifecycleModule.ADHERENCE_PROBABILITY, 1.0);
    for (int i = 0; i < 5; i++) {
      double before = (Double) person.attributes.get(LifecycleModule.ADHERENCE_PROBABILITY);
      LifecycleModule.adherence(person, time);
      double after = (Double) person.attributes.get(LifecycleModule.ADHERENCE_PROBABILITY);
      Assert.assertTrue(after < before);
    }
  }

  @Test
  public void testPercentileForBMI() {
    double percentile = LifecycleModule.percentileForBMI(18.37736191, "M", 26);
    Assert.assertEquals(0.9, percentile, 0.01);
  }
}

@@ -182,16 +182,116 @@
 t.Test;%0A
+import org.mitre.synthea.helpers.Config;%0Aimport org.mitre.synthea.helpers.PhysiologyValueGenerator;%0A
 import o
@@ -371,16 +371,67 @@
 .Person;
+%0Aimport org.mitre.synthea.world.concepts.VitalSign;
 %0A%0Apublic
@@ -2197,10 +2197,869 @@
 1);%0A  %7D%0A
+  %0A  @Test%0A  public void testPhysiologyEnabled() %7B%0A    boolean enablePhysiology = LifecycleModule.ENABLE_PHYSIOLOGY;%0A    LifecycleModule.ENABLE_PHYSIOLOGY = true;%0A    Person person = new Person(0L);%0A    %0A    // Need to set some attributes for birth to work properly%0A    person.attributes.put(Person.GENDER, %22F%22);%0A    person.attributes.put(Person.RACE, %22white%22);%0A    person.attributes.put(Person.ETHNICITY, %22english%22);%0A    %0A    LifecycleModule.birth(person, 0);%0A    %0A    // Person should have some PhysiologyValueGenerators%0A    Assert.assertEquals(person.vitalSigns.get(VitalSign.SYSTOLIC_BLOOD_PRESSURE).getClass(),%0A        PhysiologyValueGenerator.class);%0A    Assert.assertEquals(person.vitalSigns.get(VitalSign.DIASTOLIC_BLOOD_PRESSURE).getClass(),%0A        PhysiologyValueGenerator.class);%0A    %0A    LifecycleModule.ENABLE_PHYSIOLOGY = enablePhysiology;%0A  %7D%0A
 %7D%0A

add physiology enable test for LifecycleModule