//-*****************************************************************************
void testAcyclicTime3()
{
    TimeVector tvec;

    // construct with acyclic enum
    const chrono_t timePerCycle = AbcA::TimeSamplingType::AcyclicTimePerCycle();
    const size_t numSamplesPerCycle =
        AbcA::TimeSamplingType::AcyclicNumSamples();
    const size_t numSamps = 79;

    chrono_t ranTime = 0.0;
    Imath::srand48( numSamps );

    for ( size_t i = 0 ; i < numSamps ; ++i )
    {
        // sample randomly
        ranTime += Imath::drand48() * (chrono_t)i;
        tvec.push_back( ranTime );
    }

    AbcA::TimeSamplingType::AcyclicFlag acf = AbcA::TimeSamplingType::kAcyclic;

    const AbcA::TimeSamplingType tSampTyp( acf );
    const AbcA::TimeSampling tSamp( tSampTyp, tvec );

    TESTING_MESSAGE_ASSERT( tSampTyp.isAcyclic(), "Should be acyclic." );

    std::cout << "Testing acyclic time, 3" << std::endl;
    validateTimeSampling( tSamp, tSampTyp, tvec, numSamplesPerCycle,
                          timePerCycle );

    testTimeSampling( tSamp, tSampTyp, numSamps );
}
//-*****************************************************************************
void testCyclicTime4()
{
    const chrono_t startFrame = 1001.0;
    const chrono_t ftime = 1.0 / 24.0;
    const chrono_t timePerCycle = ftime;
    const size_t numSamplesPerCycle = 3;
    const size_t numSamps = 20;

    const chrono_t first = ( startFrame * ftime ) - ( ftime / 4.0 );
    const chrono_t second = startFrame * ftime;
    const chrono_t third = ( startFrame * ftime ) + ( ftime / 4.0 );

    TimeVector tvec;
    tvec.push_back( first );
    tvec.push_back( second );
    tvec.push_back( third );

    const AbcA::TimeSamplingType tst( numSamplesPerCycle, timePerCycle );
    const AbcA::TimeSampling tsamp( tst, tvec );

    TESTING_MESSAGE_ASSERT( tst.isCyclic(), "Should be cyclic." );

    std::cout << "Testing cyclic time, 4" << std::endl;

    validateTimeSampling( tsamp, tst, tvec, numSamplesPerCycle,
                          timePerCycle );

    testTimeSampling( tsamp, tst, numSamps );
}
//-*****************************************************************************
void testAcyclicTime1()
{
    TimeVector tvec;

    // construct with explicit values
    const chrono_t timePerCycle = AbcA::TimeSamplingType::AcyclicTimePerCycle();
    const size_t numSamplesPerCycle =
        AbcA::TimeSamplingType::AcyclicNumSamples();
    const size_t numSamps = 44;

    for ( size_t i = 0 ; i < numSamps ; ++i )
    {
        // sample once at each frame, starting at +0th frame
        tvec.push_back( (chrono_t)i * ( 1.0 / 24.0 ) );
    }

    const AbcA::TimeSamplingType tSampTyp( AbcA::TimeSamplingType::kAcyclic );
    const AbcA::TimeSampling tSamp( tSampTyp, tvec );

    TESTING_MESSAGE_ASSERT( tSampTyp.isAcyclic(), "Should be acyclic." );

    std::cout << "Testing acyclic time, 1" << std::endl;
    validateTimeSampling( tSamp, tSampTyp, tvec, numSamplesPerCycle,
                          timePerCycle );

    testTimeSampling( tSamp, tSampTyp, numSamps );
}
TEST_F(EnergyPlusFixture,ReverseTranslator_ScheduleDayInterval) {
  // ScheduleDayInterval time entries contain the string 'Until: ' that must be
  // stripped off before constructing a Time object. We are also more lenient in
  // making this optional.
  Workspace ws(StrictnessLevel::Draft,IddFileType(IddFileType::EnergyPlus));
  OptionalWorkspaceObject owo = ws.addObject(IdfObject(IddObjectType::Schedule_Day_Interval));
  ASSERT_TRUE(owo);
  WorkspaceObject object = *owo;
  object.setName("Heating Setpoint Design Day");
  StringVector groupValues(2u);
  groupValues[0] = std::string("Until: 12:00");
  groupValues[1] = std::string("21.1");
  object.pushExtensibleGroup(groupValues);
  groupValues[0] = std::string("24:00");
  groupValues[1] = std::string("20.5");
  object.pushExtensibleGroup(groupValues);

  ReverseTranslator translator;
  Model model = translator.translateWorkspace(ws);
  EXPECT_TRUE(translator.errors().empty());
  // There are warnings related to ws being a partial model.
  EXPECT_TRUE(translator.untranslatedIdfObjects().empty());
  ScheduleDayVector daySchedules = model.getModelObjects<ScheduleDay>();
  ASSERT_EQ(1u,daySchedules.size());
  ScheduleDay daySchedule = daySchedules[0];
  DoubleVector values = daySchedule.values();
  ASSERT_EQ(2u,values.size());
  EXPECT_DOUBLE_EQ(21.1,values[0]);
  EXPECT_DOUBLE_EQ(20.5,values[1]);
  TimeVector times = daySchedule.times();
  ASSERT_EQ(2u,times.size());
  EXPECT_EQ(Time(0,12,0),times[0]);
  EXPECT_EQ(Time(0,24,0),times[1]);
}
//-*****************************************************************************
void testDefaultTime1()
{
    // sample once at each frame
    TimeVector tvec;

    AbcA::TimeSamplingType tSampType;
    AbcA::TimeSampling tSamp;
    tvec.push_back( 0.0 );

    TESTING_MESSAGE_ASSERT( tSamp.getTimeSamplingType().isUniform(),
        "Should be uniform." );

    std::cout << "Testing default, 1" << std::endl;
    validateTimeSampling( tSamp, tSampType, tvec, 1,
                          1 );

    testTimeSampling( tSamp, tSampType, 100 );
}
//-*****************************************************************************
void testUniformTime3()
{
    // sample once at each frame, starting at +1th frame
    TimeVector tvec;
    tvec.push_back( 2.0 / 24.0 );

    const chrono_t timePerCycle = 1.0 / 24.0;
    const size_t numSamplesPerCycle = 1;
    const size_t numSamps = 49;

    const AbcA::TimeSamplingType tSampTyp( numSamplesPerCycle, timePerCycle );
    const AbcA::TimeSampling tSamp( tSampTyp, tvec );

    TESTING_MESSAGE_ASSERT( tSampTyp.isUniform(), "Should be uniform." );

    std::cout << "Testing uniform time, 3" << std::endl;
    validateTimeSampling( tSamp, tSampTyp, tvec, numSamplesPerCycle,
                          timePerCycle );

    testTimeSampling( tSamp, tSampTyp, numSamps );
}
//-*****************************************************************************
void testCyclicTime3()
{
    // shutter-open, shutter-close
    TimeVector tvec;
    tvec.push_back( 0.0 );
    tvec.push_back( 1.0 );

    const chrono_t timePerCycle = 2.0;
    const size_t numSamplesPerCycle = 2;
    const size_t numSamps = 70;

    const AbcA::TimeSamplingType tSampTyp( numSamplesPerCycle, timePerCycle );
    const AbcA::TimeSampling tSamp( tSampTyp, tvec );

    TESTING_MESSAGE_ASSERT( tSampTyp.isCyclic(), "Should be cyclic." );

    std::cout << "Testing cyclic time, 3" << std::endl;
    validateTimeSampling( tSamp, tSampTyp, tvec, numSamplesPerCycle,
                          timePerCycle );

    testTimeSampling( tSamp, tSampTyp, numSamps );
}
//-*****************************************************************************
void testCyclicTime1()
{
    // random weird cycle
    TimeVector tvec;
    tvec.push_back( -0.7 );
    tvec.push_back( -0.1 );
    tvec.push_back( 0.2 );

    const chrono_t timePerCycle = 1.0; // 0.1 more time than tvec[2] - tvec[0]
    const size_t numSamplesPerCycle = 3;
    const size_t numSamps = 97;

    const AbcA::TimeSamplingType tSampTyp( numSamplesPerCycle, timePerCycle );
    const AbcA::TimeSampling tSamp( tSampTyp, tvec );

    TESTING_MESSAGE_ASSERT( tSampTyp.isCyclic(), "Should be cyclic." );

    std::cout << "Testing cyclic time, 1" << std::endl;
    validateTimeSampling( tSamp, tSampTyp, tvec, numSamplesPerCycle,
                          timePerCycle );

    testTimeSampling( tSamp, tSampTyp, numSamps );
}
//-*****************************************************************************
void validateTimeSampling( const AbcA::TimeSampling &timeSampling,
                           const AbcA::TimeSamplingType &timeSamplingType,
                           const TimeVector &timeVector,
                           const size_t numSamplesPerCycle,
                           const chrono_t timePerCycle )
{
    const chrono_t period = timeSamplingType.getTimePerCycle();

    TESTING_MESSAGE_ASSERT( period == timePerCycle,
        "calculated cycle period does not match given time/cycle" );


    std::cout << "***********************************************************"
              << std::endl;

    if ( timeSamplingType.isUniform() )
    { std::cout << "time sampling type is uniform" << std::endl; }
    if ( timeSamplingType.isCyclic() )
    { std::cout << "time sampling type is cyclic" << std::endl; }
    if ( timeSamplingType.isAcyclic() )
    { std::cout << "time sampling type is acyclic" << std::endl; }

    std::cout << "Number of samples per cycle is "
              << timeSamplingType.getNumSamplesPerCycle()
              << std::endl << std::endl;

    std::cout << "Given times:" << std::endl;
    for ( size_t i = 0 ; i < timeVector.size() ; ++i )
    {
        std::cout << i << ": " << timeVector[i] << " " << std::endl;
    }
    std::cout << std::endl << "with a period of " << period << std::endl
              << std::endl;

    TESTING_MESSAGE_ASSERT( timeSamplingType.isAcyclic() ||
        numSamplesPerCycle == timeSampling.getNumStoredTimes(),
        "Number of samples given doesn't match number returned" );

    //-*************************************************************************
    // acyclic case
    if ( timePerCycle == AbcA::TimeSamplingType::AcyclicTimePerCycle()
         || numSamplesPerCycle == AbcA::TimeSamplingType::AcyclicNumSamples() )
    {
        TESTING_MESSAGE_ASSERT(
            timePerCycle == AbcA::TimeSamplingType::AcyclicTimePerCycle()
            && numSamplesPerCycle == AbcA::TimeSamplingType::AcyclicNumSamples(),
            "Given time and samples per cycle should be infinite."
                   );

        TESTING_MESSAGE_ASSERT( timeSamplingType.isAcyclic(),
                     "Time sampling should be acyclic." );
    }
    // uniform case
    else if ( numSamplesPerCycle == 1 )
    {
        TESTING_MESSAGE_ASSERT( timeSamplingType.isUniform(),
                     "Time sampling should be uniform." );
    }
    // cyclic case
    else if ( numSamplesPerCycle > 0 && timePerCycle > 0.0 )
    {
        TESTING_MESSAGE_ASSERT( timeSamplingType.isCyclic(),
                     "Time sampling should be cyclic." );
    }
    else
    {
        TESTING_MESSAGE_ASSERT( false, "Could not validate time sampling." );
    }
}