/*
 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"

// This test performs mocking of certain JVM functionality. This works by
// including the source file under test inside an anonymous namespace (which
// prevents linking conflicts) with the mocked symbols redefined.

// The include list should mirror the one found in the included source file -
// with the ones that should pick up the mocks removed. Those should be included
// later after the mocks have been defined.

#include "logging/log.hpp"
#include "jfr/jfrEvents.hpp"
#include "jfr/support/jfrThreadId.hpp"
#include "jfr/support/jfrThreadLocal.hpp"
#include "jfr/utilities/jfrTime.hpp"
#include "utilities/globalDefinitions.hpp"
#include "runtime/os.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadSMR.inline.hpp"

#include "unittest.hpp"

namespace {

  class MockEventThreadCPULoad : public ::EventThreadCPULoad
  {
  public:
    float user;
    float system;

  public:
    MockEventThreadCPULoad(EventStartTime timing=TIMED) : ::EventThreadCPULoad(timing) {}

    void set_user(float new_value) {
      user = new_value;
    }
    void set_system(float new_value) {
      system = new_value;
    }
  };

  class MockOs : public ::os {
  public:
    static jlong user_cpu_time;
    static jlong system_cpu_time;

    static jlong thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
      return user_sys_cpu_time ? user_cpu_time + system_cpu_time : user_cpu_time;
    }
  };

  jlong MockOs::user_cpu_time;
  jlong MockOs::system_cpu_time;

  class MockJavaThread : public ::JavaThread {
  public:
    MockJavaThread() : ::JavaThread() {}
  };

  class MockJavaThreadIteratorWithHandle
  {
  public:
    MockJavaThread* next() { return NULL; }
    int length() { return 0; }
  };

// Reincluding source files in the anonymous namespace unfortunately seems to
// behave strangely with precompiled headers (only when using gcc though)
#ifndef DONT_USE_PRECOMPILED_HEADER
#define DONT_USE_PRECOMPILED_HEADER
#endif

#define os MockOs
#define EventThreadCPULoad MockEventThreadCPULoad
#define JavaThread MockJavaThread
#define JavaThreadIteratorWithHandle MockJavaThreadIteratorWithHandle

#include "jfr/periodic/jfrThreadCPULoadEvent.hpp"
#include "jfr/periodic/jfrThreadCPULoadEvent.cpp"

#undef os
#undef EventThreadCPULoad
#undef JavaThread
#undef JavaThreadIteratorWithHandle

} // anonymous namespace

class JfrTestThreadCPULoadSingle : public ::testing::Test {
protected:
  MockJavaThread* thread;
  JfrThreadLocal* thread_data;
  MockEventThreadCPULoad event;

  void SetUp() {
    thread = new MockJavaThread();
    thread_data = thread->jfr_thread_local();
    thread_data->set_wallclock_time(0);
    thread_data->set_user_time(0);
    thread_data->set_cpu_time(0);
  }

  void TearDown() {
    delete thread;
  }

  // Fix for gcc compilation warning about unused functions
  bool TouchUnused() {
    return (&JfrThreadCPULoadEvent::send_events &&
            &JfrThreadCPULoadEvent::send_event_for_thread);
  }
};

TEST_VM_F(JfrTestThreadCPULoadSingle, SingleCpu) {
  MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;
  MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;
  EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));
  EXPECT_FLOAT_EQ(0.25, event.user);
  EXPECT_FLOAT_EQ(0.25, event.system);
}

TEST_VM_F(JfrTestThreadCPULoadSingle, MultipleCpus) {
  MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;
  MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;
  EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 2));
  EXPECT_FLOAT_EQ(0.125, event.user);
  EXPECT_FLOAT_EQ(0.125, event.system);
}

TEST_VM_F(JfrTestThreadCPULoadSingle, BelowThreshold) {
  MockOs::user_cpu_time = 100;
  MockOs::system_cpu_time = 100;
  EXPECT_FALSE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 2));
}

TEST_VM_F(JfrTestThreadCPULoadSingle, UserAboveMaximum) {

  // First call will not report above 100%
  MockOs::user_cpu_time = 200 * NANOSECS_PER_MILLISEC;
  MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;
  EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 200 * NANOSECS_PER_MILLISEC, 1));
  EXPECT_FLOAT_EQ(0.5, event.user);
  EXPECT_FLOAT_EQ(0.5, event.system);

  // Second call will see an extra 100 millisecs user time from the remainder
  EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400) * NANOSECS_PER_MILLISEC, 1));
  EXPECT_FLOAT_EQ(0.25, event.user);
  EXPECT_FLOAT_EQ(0, event.system);
}

TEST_VM_F(JfrTestThreadCPULoadSingle, SystemAboveMaximum) {

  // First call will not report above 100%
  MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;
  MockOs::system_cpu_time = 300 * NANOSECS_PER_MILLISEC;
  EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 200 * NANOSECS_PER_MILLISEC, 1));
  EXPECT_FLOAT_EQ(0, event.user);
  EXPECT_FLOAT_EQ(1, event.system);

  // Second call will see an extra 100 millisecs user and system time from the remainder
  EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400) * NANOSECS_PER_MILLISEC, 1));
  EXPECT_FLOAT_EQ(0.25, event.user);
  EXPECT_FLOAT_EQ(0.25, event.system);
}

TEST_VM_F(JfrTestThreadCPULoadSingle, SystemTimeDecreasing) {

  // As seen in an actual run - caused by different resolution for total and user time
  // Total time    User time    (Calculated system time)
  //       200          100         100
  //       210          200          10
  //       400          300         100

  MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;
  MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;
  EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));
  EXPECT_FLOAT_EQ(0.25, event.user);
  EXPECT_FLOAT_EQ(0.25, event.system);

  MockOs::user_cpu_time += 100 * NANOSECS_PER_MILLISEC;
  MockOs::system_cpu_time -= 90 * NANOSECS_PER_MILLISEC;
  EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 400) * NANOSECS_PER_MILLISEC, 1));
  EXPECT_FLOAT_EQ(0.25, event.user);
  EXPECT_FLOAT_EQ(0, event.system);

  MockOs::user_cpu_time += 100 * NANOSECS_PER_MILLISEC;
  MockOs::system_cpu_time += 90 * NANOSECS_PER_MILLISEC;
  EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));
  EXPECT_FLOAT_EQ(0.25, event.user);
  EXPECT_FLOAT_EQ(0, event.system);
}
