// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "session/session_handler.h"

#include <algorithm>
#include <string>
#include <vector>

#include "base/file_util.h"
#include "base/port.h"
#include "base/scoped_ptr.h"
#include "engine/engine_factory.h"
#include "session/commands.pb.h"
#include "session/random_keyevents_generator.h"
#include "session/session_handler_test_util.h"
#include "testing/base/public/gunit.h"

#ifdef OS_ANDROID
#include "base/mmap.h"
#include "base/singleton.h"
#include "data_manager/android/android_data_manager.h"
#endif

namespace {
uint32 GenerateRandomSeed() {
  uint32 seed = 0;
  mozc::Util::GetRandomSequence(reinterpret_cast<char *>(&seed),
                                sizeof(seed));
  return seed;
}
}  // namespace

// There is no DEFINE_uint32.
DEFINE_uint64(random_seed, GenerateRandomSeed(),
              "Random seed value. "
              "This value will be interpreted as uint32.");
DECLARE_string(test_srcdir);
DECLARE_string(test_tmpdir);

namespace mozc {

using session::testing::SessionHandlerTestBase;
using session::testing::TestSessionClient;

namespace {
#ifdef OS_ANDROID
// In actual libmozc.so usage, the dictionary data will be given via JNI call
// because only Java side code knows where the data is.
// On native code unittest, we cannot do it, so instead we mmap the files
// and use it.
// Note that this technique works here because the no other test code doesn't
// link to this binary.
// TODO(hidehiko): Get rid of this hack by refactoring Engine/DataManager
// related code.
class AndroidInitializer {
 private:
  AndroidInitializer() {
    string dictionary_data_path = FileUtil::JoinPath(
        FLAGS_test_srcdir, "embedded_data/dictionary_data");
    CHECK(dictionary_mmap_.Open(dictionary_data_path.c_str(), "r"));
    android::AndroidDataManager::SetDictionaryData(
        dictionary_mmap_.begin(), dictionary_mmap_.size());

    string connection_data_path = FileUtil::JoinPath(
        FLAGS_test_srcdir, "embedded_data/connection_data");
    CHECK(connection_mmap_.Open(connection_data_path.c_str(), "r"));
    android::AndroidDataManager::SetConnectionData(
        connection_mmap_.begin(), connection_mmap_.size());
    LOG(ERROR) << "mmap data initialized.";
  }

  friend class Singleton<AndroidInitializer>;

  Mmap dictionary_mmap_;
  Mmap connection_mmap_;

  DISALLOW_COPY_AND_ASSIGN(AndroidInitializer);
};
#endif  // OS_ANDROID
}  // namespace

class SessionHandlerStressTest : public SessionHandlerTestBase {
 protected:
  virtual EngineInterface *CreateEngine() {
#ifdef OS_ANDROID
    Singleton<AndroidInitializer>::get();
#endif  // OS_ANDROID
    return EngineFactory::Create();
  }
};

TEST_F(SessionHandlerStressTest, BasicStressTest) {
  vector<commands::KeyEvent> keys;
  commands::Output output;
  scoped_ptr<EngineInterface> engine(EngineFactory::Create());
  TestSessionClient client(engine.get());
  size_t keyevents_size = 0;
  const size_t kMaxEventSize = 10000;
  ASSERT_TRUE(client.CreateSession());

  const uint32 random_seed = static_cast<uint32>(FLAGS_random_seed);
  LOG(INFO) << "Random seed: " << random_seed;
  session::RandomKeyEventsGenerator::InitSeed(random_seed);
  while (keyevents_size < kMaxEventSize) {
    keys.clear();
    session::RandomKeyEventsGenerator::GenerateSequence(&keys);
    for (size_t i = 0; i < keys.size(); ++i) {
      ++keyevents_size;
      EXPECT_TRUE(client.TestSendKey(keys[i], &output));
      EXPECT_TRUE(client.SendKey(keys[i], &output));
    }
  }
  EXPECT_TRUE(client.DeleteSession());
}

}  // namespace mozc
