// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This header defines two macros, COBALT_WRAP_SIMPLE_MAIN() and
// COBALT_WRAP_BASE_MAIN(). Simple main is for programs that are
// run-and-terminate, like unit tests. Base main is for programs that need a
// main message loop, and will terminate when the quit_closure is called.

#ifndef COBALT_BASE_WRAP_MAIN_H_
#define COBALT_BASE_WRAP_MAIN_H_

#include "base/at_exit.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "cobalt/base/init_cobalt.h"
#if defined(OS_STARBOARD)
#include "starboard/event.h"
#else
typedef void SbEvent;
#endif

namespace cobalt {
namespace wrap_main {

// A main-style function.
typedef int (*MainFunction)(int argc, char** argv);

// A start-style function.
typedef void (*StartFunction)(int argc, char** argv, const char* link,
                              const base::Closure& quit_closure);

// A function type that can be called at shutdown.
typedef void (*StopFunction)();

// A function type that can be called to handle other SbEvents.
typedef void (*EventFunction)(const SbEvent* event);

// No-operation function that can be passed into start_function if no start work
// is needed.
void NoopStartFunction(int /*argc*/, char** /*argv*/, const char* /*link*/,
                       const base::Closure& /*quit_closure*/) {}

// No-operation function that can be passed into event_function if no other
// event handling work is needed.
void NoopEventFunction(const SbEvent* /*event*/) {}

// No-operation function that can be passed into stop_function if no stop work
// is needed.
void NoopStopFunction() {}

}  // namespace wrap_main
}  // namespace cobalt

#if defined(OS_STARBOARD)
#include "cobalt/base/wrap_main_starboard.h"
#else

namespace cobalt {
namespace wrap_main {

template <MainFunction main_function>
int SimpleMain(int argc, char** argv) {
  base::AtExitManager at_exit;
  InitCobalt(argc, argv, NULL);
  return main_function(argc, argv);
}

template <StartFunction start_function, StopFunction stop_function>
int BaseMain(int argc, char** argv) {
  base::AtExitManager at_exit;
  InitCobalt(argc, argv, NULL);

  MessageLoopForUI message_loop;
  base::PlatformThread::SetName("Main");
  message_loop.set_thread_name("Main");

  DCHECK(!message_loop.is_running());
  base::RunLoop run_loop;

  start_function(argc, argv, NULL, run_loop.QuitClosure());
  run_loop.Run();
  stop_function();

  return 0;
}

// Calls |main_function| at startup, creates an AtExitManager and calls
// InitCobalt, and terminates once it is completed.
#define COBALT_WRAP_SIMPLE_MAIN(main_function)                         \
  int main(int argc, char** argv) {                                    \
    return ::cobalt::wrap_main::SimpleMain<main_function>(argc, argv); \
  }

// Creates a MessageLoop and an AtExitManager, calls |start_function|, and
// terminates once the MessageLoop terminates, calling |stop_function| on the
// way out.
#define COBALT_WRAP_BASE_MAIN(start_function, stop_function)                   \
  int main(int argc, char** argv) {                                            \
    return ::cobalt::wrap_main::BaseMain<start_function, stop_function>(argc,  \
                                                                        argv); \
  }

// Like COBALT_WRAP_BASE_MAIN, but supports an event_function to forward
// non-application events to.
#define COBALT_WRAP_EVENT_MAIN(start_function, event_function, stop_function) \
  COBALT_WRAP_BASE_MAIN(start_function, stop_function)

// The generic main wrapper that initializes the main MessageLoop and
// AtExitManager, supports a preload function, start function, event handler,
// and stop function.
#define COBALT_WRAP_MAIN(preload_function, start_function, event_function, \
                         stop_function)                                    \
  COBALT_WRAP_BASE_MAIN(start_function, stop_function)

}  // namespace wrap_main
}  // namespace cobalt

#endif  // defined(OS_STARBOARD)

#endif  // COBALT_BASE_WRAP_MAIN_H_
