// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdarg.h>
#include <string.h>

#include "base/android/path_utils.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_pump_android.h"
#include "base/path_service.h"
#include "base/synchronization/waitable_event.h"

namespace {

struct RunState {
  RunState(base::MessagePump::Delegate* delegate, int run_depth)
      : delegate(delegate),
        run_depth(run_depth),
        should_quit(false) {
  }

  base::MessagePump::Delegate* delegate;

  // Used to count how many Run() invocations are on the stack.
  int run_depth;

  // Used to flag that the current Run() invocation should return ASAP.
  bool should_quit;
};

RunState* g_state = NULL;

// A singleton WaitableEvent wrapper so we avoid a busy loop in
// MessagePumpForUIStub. Other platforms use the native event loop which blocks
// when there are no pending messages.
class Waitable {
 public:
   static Waitable* GetInstance() {
     return Singleton<Waitable>::get();
   }

   // Signals that there are more work to do.
   void Signal() {
     waitable_event_.Signal();
   }

   // Blocks until more work is scheduled.
   void Block() {
     waitable_event_.Wait();
   }

   void Quit() {
     g_state->should_quit = true;
     Signal();
   }

 private:
  friend struct DefaultSingletonTraits<Waitable>;

  Waitable()
      : waitable_event_(false, false) {
  }

  base::WaitableEvent waitable_event_;

  DISALLOW_COPY_AND_ASSIGN(Waitable);
};

// The MessagePumpForUI implementation for test purpose.
class MessagePumpForUIStub : public base::MessagePumpForUI {
  virtual ~MessagePumpForUIStub() {}

  virtual void Start(base::MessagePump::Delegate* delegate) OVERRIDE {
    NOTREACHED() << "The Start() method shouldn't be called in test, using"
        " Run() method should be used.";
  }

  virtual void Run(base::MessagePump::Delegate* delegate) OVERRIDE {
    // The following was based on message_pump_glib.cc, except we're using a
    // WaitableEvent since there are no native message loop to use.
    RunState state(delegate, g_state ? g_state->run_depth + 1 : 1);

    RunState* previous_state = g_state;
    g_state = &state;

    bool more_work_is_plausible = true;

    for (;;) {
      if (!more_work_is_plausible) {
        Waitable::GetInstance()->Block();
        if (g_state->should_quit)
          break;
      }

      more_work_is_plausible = g_state->delegate->DoWork();
      if (g_state->should_quit)
        break;

      base::TimeTicks delayed_work_time;
      more_work_is_plausible |=
          g_state->delegate->DoDelayedWork(&delayed_work_time);
      if (g_state->should_quit)
        break;

      if (more_work_is_plausible)
        continue;

      more_work_is_plausible = g_state->delegate->DoIdleWork();
      if (g_state->should_quit)
        break;

      more_work_is_plausible |= !delayed_work_time.is_null();
    }

    g_state = previous_state;
  }

  virtual void Quit() OVERRIDE {
    Waitable::GetInstance()->Quit();
  }

  virtual void ScheduleWork() OVERRIDE {
    Waitable::GetInstance()->Signal();
  }

  virtual void ScheduleDelayedWork(
      const base::TimeTicks& delayed_work_time) OVERRIDE {
    Waitable::GetInstance()->Signal();
  }
};

scoped_ptr<base::MessagePump> CreateMessagePumpForUIStub() {
  return scoped_ptr<base::MessagePump>(new MessagePumpForUIStub());
};

// Provides the test path for DIR_MODULE and DIR_ANDROID_APP_DATA.
bool GetTestProviderPath(int key, base::FilePath* result) {
  switch (key) {
    case base::DIR_MODULE: {
      return base::android::GetExternalStorageDirectory(result);
    }
    case base::DIR_ANDROID_APP_DATA: {
      // For tests, app data is put in external storage.
      return base::android::GetExternalStorageDirectory(result);
    }
    default:
      return false;
  }
}

void InitPathProvider(int key) {
  base::FilePath path;
  // If failed to override the key, that means the way has not been registered.
  if (GetTestProviderPath(key, &path) && !PathService::Override(key, path))
    PathService::RegisterProvider(&GetTestProviderPath, key, key + 1);
}

}  // namespace

namespace base {

void InitAndroidTestLogging() {
  logging::LoggingSettings settings;
  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
  logging::InitLogging(settings);
  // To view log output with IDs and timestamps use "adb logcat -v threadtime".
  logging::SetLogItems(false,    // Process ID
                       false,    // Thread ID
                       false,    // Timestamp
                       false);   // Tick count
}

void InitAndroidTestPaths() {
  InitPathProvider(DIR_MODULE);
  InitPathProvider(DIR_ANDROID_APP_DATA);
}

void InitAndroidTestMessageLoop() {
  if (!MessageLoop::InitMessagePumpForUIFactory(&CreateMessagePumpForUIStub))
    LOG(INFO) << "MessagePumpForUIFactory already set, unable to override.";
}

void InitAndroidTest() {
  InitAndroidTestLogging();
  InitAndroidTestPaths();
  InitAndroidTestMessageLoop();
}
}  // namespace base
