// 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.

#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/common/log.h"
#include "starboard/input.h"
#include "starboard/key.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() {
  if (!directfb_) {
    // 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().";
    }
  }
  return directfb_;
}

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

void ApplicationDirectFB::Initialize() {
}

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_));

  if (directfb_) {
    // 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
    directfb_ = nullptr;
  }
}

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->timestamp = SbTimeGetMonotonicNow();
    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
