// Copyright (c) 2010 The Chromium OS 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 <unistd.h>

#include <cmath>
#include <cstdlib>
#include <ctime>

extern "C" {
#include <X11/Xlib.h>
}

#include <gflags/gflags.h>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "window_manager/callback.h"
#include "window_manager/compositor/real_compositor.h"
#if defined(COMPOSITOR_OPENGL)
#include "window_manager/compositor/gl/real_gl_interface.h"
#elif defined(COMPOSITOR_OPENGLES)
#include "window_manager/compositor/gles/real_gles2_interface.h"
#endif
#include "window_manager/event_loop.h"
#include "window_manager/profiler.h"
#include "window_manager/real_dbus_interface.h"
#include "window_manager/util.h"
#include "window_manager/window_manager.h"
#include "window_manager/x11/real_x_connection.h"

DEFINE_string(display, "",
              "X Display to connect to (overrides DISPLAY env var).");
DEFINE_bool(logtostderr, false,
            "Log to stderr (see --logged_{in,out}_log_dir otherwise)");
DEFINE_int32(pause_at_start, 0,
             "Specify this to pause for N seconds at startup");
DEFINE_string(profile_dir, "./profile",
              "Directory where profiles should be written; created if it "
              "doesn't exist.");
DEFINE_int32(profile_max_samples, 200,
             "Maximum number of samples (buffer size) for profiler.");
DEFINE_bool(start_profiler, false, "Start profiler at window manager startup.");

using std::string;
using window_manager::EventLoop;
using window_manager::RealCompositor;
using window_manager::RealDBusInterface;
#if defined(COMPOSITOR_OPENGL)
using window_manager::RealGLInterface;
#elif defined(COMPOSITOR_OPENGLES)
using window_manager::RealGles2Interface;
#else
#error COMPOSITOR_OPENGL or COMPOSITOR_OPENGLES must be defined
#endif
using window_manager::RealXConnection;
using window_manager::WindowManager;
using window_manager::util::GetTimeAsString;
using window_manager::util::SetUpLogSymlink;

// This should be adjusted according to number of PROFILER_MARKER_*
static const int kMaxNumProfilerSymbols = 100;

// Handler called by Chrome logging code on failed asserts.
static void HandleLogAssert(const string& str) {
  abort();
}

// Handler called in response to Xlib I/O errors.  We install this so we won't
// generate a window manager crash dump whenever the X server crashes.
static int HandleXIOError(Display* display) {
  LOG(ERROR) << "Got X I/O error (probably lost connection to server); exiting";
  _exit(EXIT_FAILURE);
}

int main(int argc, char** argv) {
  base::AtExitManager exit_manager;  // needed by base::Singleton

  google::ParseCommandLineFlags(&argc, &argv, true);
  if (!FLAGS_display.empty())
    setenv("DISPLAY", FLAGS_display.c_str(), 1);

  CommandLine::Init(argc, argv);
  if (FLAGS_pause_at_start > 0)
    sleep(FLAGS_pause_at_start);

  // Just log to stderr initially; WindowManager will re-initialize to
  // switch to a file once we know whether we're logged in or not if
  // --logtostderr is false.
  logging::InitLogging(NULL,
                       logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
                       logging::DONT_LOCK_LOG_FILE,
                       logging::APPEND_TO_OLD_LOG_FILE);
  logging::SetLogItems(false,  // enable_process_id
                       false,  // enable_thread_id
                       true,   // enable_timestamp
                       true);  // enable_tickcount

  // Chrome's logging code uses int3 to send SIGTRAP in response to failed
  // asserts, but Breakpad only installs signal handlers for SEGV, ABRT,
  // FPE, ILL, and BUS.  Use our own function to send ABRT instead.
  logging::SetLogAssertHandler(HandleLogAssert);

#if defined(PROFILE_BUILD)
  const string profile_basename = StringPrintf(
      "prof_%s.%s", WindowManager::GetWmName(),
      GetTimeAsString(::time(NULL)).c_str());

  if (!file_util::CreateDirectory(FilePath(FLAGS_profile_dir))) {
    LOG(ERROR) << "Unable to create profiling directory " << FLAGS_profile_dir;
  } else {
    SetUpLogSymlink(StringPrintf("%s/prof_%s.LATEST",
                                 FLAGS_profile_dir.c_str(),
                                 WindowManager::GetWmName()),
                    profile_basename);
  }

  const string profile_path = FLAGS_profile_dir + "/" + profile_basename;
  Singleton<window_manager::Profiler>()->Start(
      new window_manager::ProfilerWriter(FilePath(profile_path)),
      kMaxNumProfilerSymbols, FLAGS_profile_max_samples);

  Singleton<window_manager::DynamicMarker>()->set_profiler(
      Singleton<window_manager::Profiler>::get());

  if (!FLAGS_start_profiler) {
    Singleton<window_manager::Profiler>()->Pause();
  }
#endif

  const char* display_name = getenv("DISPLAY");
  Display* display = XOpenDisplay(display_name);
  if (!display) {
    LOG(ERROR) << "Unable to open "
               << (display_name ? display_name : "default display");
    return EXIT_FAILURE;
  }
  XSetIOErrorHandler(HandleXIOError);

  RealXConnection xconn(display);
  EventLoop event_loop;
#if defined(COMPOSITOR_OPENGL)
  RealGLInterface gl_interface(&xconn);
#elif defined(COMPOSITOR_OPENGLES)
  RealGles2Interface gl_interface(&xconn);
#endif
  RealCompositor compositor(&event_loop, &xconn, &gl_interface);
  RealDBusInterface dbus;
  dbus.Init();

  WindowManager wm(&event_loop, &xconn, &compositor, &dbus);
  wm.set_initialize_logging(!FLAGS_logtostderr);
  wm.Init();

  // TODO: Need to also use XAddConnectionWatch()?
  const int x11_fd = xconn.GetConnectionFileDescriptor();
  LOG(INFO) << "X11 connection is on fd " << x11_fd;
  event_loop.AddFileDescriptor(
      x11_fd, NewPermanentCallback(&wm, &WindowManager::ProcessPendingEvents));
  event_loop.AddPrePollCallback(
      NewPermanentCallback(&wm, &WindowManager::ProcessPendingEvents));

  event_loop.Run();
  return EXIT_SUCCESS;
}
