// Copyright 2016 Google Inc. 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.

#include "starboard/shared/directfb/application_directfb.h"

#include <algorithm>
#include <iomanip>

#include <directfb/directfb_version.h>  // NOLINT(build/include_order)

// Anything less than 1.7.x needs special behavior on teardown.
// Issue confirmed on 1.7.7, and separate issue perhaps seen on 1.2.x
#define NEEDS_DIRECTFB_TEARDOWN_WORKAROUND \
    ((DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION <= 7))

#if NEEDS_DIRECTFB_TEARDOWN_WORKAROUND
#include <setjmp.h>
#include <signal.h>
#include <unistd.h>
#endif

#include "starboard/input.h"
#include "starboard/key.h"
#include "starboard/log.h"
#include "starboard/memory.h"
#include "starboard/shared/directfb/window_internal.h"
#include "starboard/shared/posix/time_internal.h"
#include "starboard/shared/starboard/audio_sink/audio_sink_internal.h"
#include "starboard/time.h"

namespace starboard {

namespace {

SbKey DFBKeyEventToSbKey(const DFBInputEvent& event) {
  SB_DCHECK(event.type == DIET_KEYPRESS || event.type == DIET_KEYRELEASE);
  SB_DCHECK(event.flags & DIEF_KEYID);

  // The following Starboard keys are currently not being generated by the code
  // below:
  //   kSbKeyKana
  //   kSbKeyHangul
  //   kSbKeyHanja
  //   kSbKeyKanji
  //   kSbKeyConvert
  //   kSbKeyNonconvert
  //   kSbKeyDbeDbcschar
  //   kSbKeyExecute
  //   kSbKeyF13
  //   kSbKeyF14
  //   kSbKeyF15
  //   kSbKeyF16
  //   kSbKeyF17
  //   kSbKeyF18
  //   kSbKeyF19
  //   kSbKeyF20
  //   kSbKeyF21
  //   kSbKeyF22
  //   kSbKeyF23
  //   kSbKeyF24
  //   kSbKeyBrowserSearch
  //   kSbKeyBrowserHome
  //   kSbKeyMediaLaunchApp
  //   kSbKeyWla
  //   kSbKeyBrightnessDown
  //   kSbKeyBrightnessUp
  //   kSbKeyKbdBrightnessDown
  //   kSbKeyKbdBrightnessUp
  //   kSbKeyBrowserBack
  //   kSbKeyBrowserForward
  //   kSbKeyBrowserRefresh
  //   kSbKeyBrowserStop
  //   kSbKeyBrowserFavorites

  if (event.flags & DIEF_KEYSYMBOL) {
    switch (event.key_symbol) {
      case DIKS_CLEAR:
        return kSbKeyClear;
      case DIKS_SELECT:
        return kSbKeySelect;
      case DIKS_HELP:
        return kSbKeyHelp;
      case DIKS_MENU:
        return kSbKeyApps;

      // For supporting multimedia buttons on a USB keyboard.
      case DIKS_MUTE:
        return kSbKeyVolumeMute;
      case DIKS_VOLUME_DOWN:
        return kSbKeyVolumeDown;
      case DIKS_VOLUME_UP:
        return kSbKeyVolumeUp;
      case DIKS_NEXT:
        return kSbKeyMediaNextTrack;
      case DIKS_PREVIOUS:
        return kSbKeyMediaPrevTrack;
      case DIKS_STOP:
        return kSbKeyMediaStop;
      case DIKS_PLAY:
        return kSbKeyMediaPlayPause;
      case DIKS_MAIL:
        return kSbKeyMediaLaunchMail;
      case DIKS_CALCULATOR:
        return kSbKeyMediaLaunchApp2;
      case DIKS_POWER:
      case DIKS_POWER2:
        return kSbKeyPower;

      default: {
        // Follow through to switching on event.key_id.
      }
    }
  }

  switch (event.key_id) {
    case DIKI_BACKSPACE:
      return kSbKeyBack;
    case DIKI_DELETE:
      return kSbKeyDelete;
    case DIKI_TAB:
      return kSbKeyTab;
    case DIKI_ENTER:
    case DIKI_KP_ENTER:
      return kSbKeyReturn;
    case DIKI_SPACE:
      return kSbKeySpace;
    case DIKI_HOME:
      return kSbKeyHome;
    case DIKI_END:
      return kSbKeyEnd;
    case DIKI_PAGE_UP:
      return kSbKeyPrior;
    case DIKI_PAGE_DOWN:
      return kSbKeyNext;
    case DIKI_LEFT:
      return kSbKeyLeft;
    case DIKI_RIGHT:
      return kSbKeyRight;
    case DIKI_DOWN:
      return kSbKeyDown;
    case DIKI_UP:
      return kSbKeyUp;
    case DIKI_ESCAPE:
      return kSbKeyEscape;
    case DIKI_A:
      return kSbKeyA;
    case DIKI_B:
      return kSbKeyB;
    case DIKI_C:
      return kSbKeyC;
    case DIKI_D:
      return kSbKeyD;
    case DIKI_E:
      return kSbKeyE;
    case DIKI_F:
      return kSbKeyF;
    case DIKI_G:
      return kSbKeyG;
    case DIKI_H:
      return kSbKeyH;
    case DIKI_I:
      return kSbKeyI;
    case DIKI_J:
      return kSbKeyJ;
    case DIKI_K:
      return kSbKeyK;
    case DIKI_L:
      return kSbKeyL;
    case DIKI_M:
      return kSbKeyM;
    case DIKI_N:
      return kSbKeyN;
    case DIKI_O:
      return kSbKeyO;
    case DIKI_P:
      return kSbKeyP;
    case DIKI_Q:
      return kSbKeyQ;
    case DIKI_R:
      return kSbKeyR;
    case DIKI_S:
      return kSbKeyS;
    case DIKI_T:
      return kSbKeyT;
    case DIKI_U:
      return kSbKeyU;
    case DIKI_V:
      return kSbKeyV;
    case DIKI_W:
      return kSbKeyW;
    case DIKI_X:
      return kSbKeyX;
    case DIKI_Y:
      return kSbKeyY;
    case DIKI_Z:
      return kSbKeyZ;

    case DIKI_0:
    case DIKI_1:
    case DIKI_2:
    case DIKI_3:
    case DIKI_4:
    case DIKI_5:
    case DIKI_6:
    case DIKI_7:
    case DIKI_8:
    case DIKI_9:
      return static_cast<SbKey>(kSbKey0 + (event.key_id - DIKI_0));

    case DIKI_KP_0:
    case DIKI_KP_1:
    case DIKI_KP_2:
    case DIKI_KP_3:
    case DIKI_KP_4:
    case DIKI_KP_5:
    case DIKI_KP_6:
    case DIKI_KP_7:
    case DIKI_KP_8:
    case DIKI_KP_9:
      return static_cast<SbKey>(kSbKeyNumpad0 + (event.key_id - DIKI_KP_0));

    case DIKI_KP_MULT:
      return kSbKeyMultiply;
    case DIKI_KP_PLUS:
      return kSbKeyAdd;
    case DIKI_KP_SEPARATOR:
      return kSbKeySeparator;
    case DIKI_KP_MINUS:
      return kSbKeySubtract;
    case DIKI_KP_DECIMAL:
      return kSbKeyDecimal;
    case DIKI_KP_DIV:
      return kSbKeyDivide;
    case DIKI_KP_EQUAL:
    case DIKI_EQUALS_SIGN:
      return kSbKeyOemPlus;
    case DIKI_COMMA:
      return kSbKeyOemComma;
    case DIKI_MINUS_SIGN:
      return kSbKeyOemMinus;
    case DIKI_PERIOD:
      return kSbKeyOemPeriod;
    case DIKI_SEMICOLON:
      return kSbKeyOem1;
    case DIKI_SLASH:
      return kSbKeyOem2;
    case DIKI_QUOTE_LEFT:
      return kSbKeyOem3;
    case DIKI_BRACKET_LEFT:
      return kSbKeyOem4;
    case DIKI_BACKSLASH:
      return kSbKeyOem5;
    case DIKI_BRACKET_RIGHT:
      return kSbKeyOem6;
    case DIKI_QUOTE_RIGHT:
      return kSbKeyOem7;
    case DIKI_SHIFT_L:
    case DIKI_SHIFT_R:
      return kSbKeyShift;
    case DIKI_CONTROL_L:
    case DIKI_CONTROL_R:
      return kSbKeyControl;
    case DIKI_META_L:
    case DIKI_META_R:
    case DIKI_ALT_L:
    case DIKI_ALT_R:
      return kSbKeyMenu;
    case DIKI_PAUSE:
      return kSbKeyPause;
    case DIKI_CAPS_LOCK:
      return kSbKeyCapital;
    case DIKI_NUM_LOCK:
      return kSbKeyNumlock;
    case DIKI_SCROLL_LOCK:
      return kSbKeyScroll;
    case DIKI_PRINT:
      return kSbKeyPrint;
    case DIKI_INSERT:
      return kSbKeyInsert;
    case DIKI_SUPER_L:
      return kSbKeyLwin;
    case DIKI_SUPER_R:
      return kSbKeyRwin;
    case DIKI_F1:
    case DIKI_F2:
    case DIKI_F3:
    case DIKI_F4:
    case DIKI_F5:
    case DIKI_F6:
    case DIKI_F7:
    case DIKI_F8:
    case DIKI_F9:
    case DIKI_F10:
    case DIKI_F11:
    case DIKI_F12:
      return static_cast<SbKey>(kSbKeyF1 + (event.key_id - DIKI_F1));
    case DIKI_KP_F1:
    case DIKI_KP_F2:
    case DIKI_KP_F3:
    case DIKI_KP_F4:
      return static_cast<SbKey>(kSbKeyF1 + (event.key_id - DIKI_KP_F1));

    default: {
      SB_DLOG(WARNING) << "Unknown event.key_id: 0x" << std::hex
                       << event.key_id;
    }
  }

  return kSbKeyUnknown;
}  // NOLINT(readability/fn_size)

SbKeyLocation DFBKeyEventToSbKeyLocation(const DFBInputEvent& event) {
  SB_DCHECK(event.type == DIET_KEYPRESS || event.type == DIET_KEYRELEASE);
  SB_DCHECK(event.flags & DIEF_KEYID);

  switch (event.key_id) {
    case DIKI_SHIFT_L:
    case DIKI_CONTROL_L:
    case DIKI_META_L:
    case DIKI_ALT_L:
      return kSbKeyLocationLeft;
    case DIKI_SHIFT_R:
    case DIKI_CONTROL_R:
    case DIKI_META_R:
    case DIKI_ALT_R:
      return kSbKeyLocationRight;

    default: {}
  }

  return kSbKeyLocationUnspecified;
}

unsigned int DFBKeyEventToSbKeyModifiers(const DFBInputEvent& event) {
  unsigned int key_modifiers = kSbKeyModifiersNone;
  if (event.modifiers & DIMM_ALT) {
    key_modifiers |= kSbKeyModifiersAlt;
  }
  if (event.modifiers & DIMM_CONTROL) {
    key_modifiers |= kSbKeyModifiersCtrl;
  }
  if (event.modifiers & DIMM_SHIFT) {
    key_modifiers |= kSbKeyModifiersShift;
  }
  return key_modifiers;
}

}  // namespace

ApplicationDirectFB::ApplicationDirectFB()
    : directfb_(NULL), window_(kSbWindowInvalid) {
  SbAudioSinkPrivate::Initialize();
}

ApplicationDirectFB::~ApplicationDirectFB() {
  SbAudioSinkPrivate::TearDown();
}

SbWindow ApplicationDirectFB::CreateWindow(const SbWindowOptions* options) {
  if (SbWindowIsValid(window_)) {
    // Cannot create a window if one is already created.
    return kSbWindowInvalid;
  }

  window_ = new SbWindowPrivate(GetDirectFB(), options);
  return window_;
}

bool ApplicationDirectFB::DestroyWindow(SbWindow window) {
  if (!SbWindowIsValid(window)) {
    return false;
  }
  if (window != window_) {
    return false;
  }

  delete window_;
  window_ = kSbWindowInvalid;

  return true;
}

IDirectFB* ApplicationDirectFB::GetDirectFB() {
  return directfb_;
}

SbWindow ApplicationDirectFB::GetWindow() {
  return window_;
}

void ApplicationDirectFB::Initialize() {
  // We only support one DirectFB device, so set it up and return it here.
  int argc = 0;
  if (DirectFBInit(&argc, NULL) != DFB_OK) {
    SB_NOTREACHED() << "Error calling DirectFBInit().";
  }

  // Setup DirectFB to not provide any default window background.
  DirectFBSetOption("bg-none", NULL);
  // Setup DirectFB to not show their default mouse cursor.
  DirectFBSetOption("no-cursor", NULL);

  // Create the DirectFB object.
  if (DirectFBCreate(&directfb_) != DFB_OK) {
    SB_NOTREACHED() << "Error calling DirectFBCreate().";
  }
  if (directfb_->SetCooperativeLevel(directfb_, DFSCL_NORMAL) != DFB_OK) {
    SB_NOTREACHED() << "Error calling SetCooperativeLevel().";
  }
}

namespace {

#if NEEDS_DIRECTFB_TEARDOWN_WORKAROUND
jmp_buf signal_jmp_buffer;

void on_segv(int sig /*, siginfo_t *info, void *ucontext*/) {
  siglongjmp(signal_jmp_buffer, 1);
}
#endif  // NEEDS_DIRECTFB_TEARDOWN_WORKAROUND

}  // namespace

void ApplicationDirectFB::Teardown() {
  SB_DCHECK(!SbWindowIsValid(window_));

  // DirectFB 1.7.7 has an uninitialized variable that causes
  // crashes at teardown time.
  // We swallow this crash here so that automated testing continues to
  // work.
  // See: http://lists.openembedded.org/pipermail/openembedded-core/2016-June/122843.html
  // We've also seen teardown problems on 1.2.x.
#if NEEDS_DIRECTFB_TEARDOWN_WORKAROUND
  if (sigsetjmp(signal_jmp_buffer, 1)) {
    SB_LOG(WARNING) << "DirectFB segv during teardown. Expect memory leaks.";
    // Calling _exit here to skip atexit handlers because we've seen
    // directfb 1.2.10 hang on shutdown after this during an atexit handler.
    // Note we exit with success so unit tests pass.
    _exit(0);
  } else {
    struct sigaction sigaction_config;
    SbMemorySet(&sigaction_config, 0, sizeof(sigaction_config));

    sigaction_config.sa_handler = on_segv;
    sigemptyset(&sigaction_config.sa_mask);
    sigaction_config.sa_flags = 0;

    // Unblock SIGSEGV, which has been blocked earlier (perhaps by libdirectfb)
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGSEGV);
    sigprocmask(SIG_UNBLOCK, &set, nullptr);

    int err = sigaction(SIGSEGV, &sigaction_config, nullptr);

    directfb_->Release(directfb_);
  }
#else  // NEEDS_DIRECTFB_TEARDOWN_WORKAROUND
  directfb_->Release(directfb_);
#endif  // NEEDS_DIRECTFB_TEARDOWN_WORKAROUND
}

shared::starboard::Application::Event*
ApplicationDirectFB::PollNextSystemEvent() {
  DFBInputEvent dfb_event;
  if (window_->event_buffer->GetEvent(window_->event_buffer,
                                      DFB_EVENT(&dfb_event)) == DFB_OK) {
    return DFBEventToEvent(dfb_event);
  } else {
    return NULL;
  }
}

shared::starboard::Application::Event*
ApplicationDirectFB::WaitForSystemEventWithTimeout(SbTime time) {
  unsigned int seconds = time / kSbTimeSecond;
  unsigned int milliseconds = (time % kSbTimeSecond) / kSbTimeMillisecond;
  window_->event_buffer->WaitForEventWithTimeout(window_->event_buffer, seconds,
                                                 milliseconds);

  return PollNextSystemEvent();
}

bool ApplicationDirectFB::MayHaveSystemEvents() {
  return SbWindowIsValid(window_);
}

void ApplicationDirectFB::WakeSystemEventWait() {
  if (IsCurrentThread()) {
    return;
  }

  SB_DCHECK(SbWindowIsValid(window_));

  // The window is valid, call WakeUp() to break out of
  // WaitForEventWithTimeout(), if a thread is waiting in that function right
  // now.
  window_->event_buffer->WakeUp(window_->event_buffer);
}

shared::starboard::Application::Event* ApplicationDirectFB::DFBEventToEvent(
    const DFBInputEvent& event) {
  const int kKeyboardDeviceId = 1;

  if (event.type == DIET_KEYPRESS || event.type == DIET_KEYRELEASE) {
    SB_DCHECK(event.flags & DIEF_KEYID);

    SbInputData* data = new SbInputData();
    SbMemorySet(data, 0, sizeof(*data));
    data->window = window_;
    SB_DCHECK(SbWindowIsValid(data->window));
    data->type = (event.type == DIET_KEYPRESS ? kSbInputEventTypePress
                                              : kSbInputEventTypeUnpress);
    data->device_type = kSbInputDeviceTypeKeyboard;
    data->device_id = kKeyboardDeviceId;
    data->key = DFBKeyEventToSbKey(event);
    data->key_location = DFBKeyEventToSbKeyLocation(event);
    data->key_modifiers = DFBKeyEventToSbKeyModifiers(event);
    return new Event(kSbEventTypeInput, data, &DeleteDestructor<SbInputData>);
  }

  return NULL;
}

}  // namespace starboard
