// 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/android/shared/application_android.h"

#include <android/looper.h>
#include <android/native_activity.h>
#include <time.h>
#include <unistd.h>

#include <string>
#include <vector>

#include "starboard/accessibility.h"
#include "starboard/android/shared/file_internal.h"
#include "starboard/android/shared/input_events_generator.h"
#include "starboard/android/shared/jni_env_ext.h"
#include "starboard/android/shared/jni_utils.h"
#include "starboard/android/shared/window_internal.h"
#include "starboard/common/condition_variable.h"
#include "starboard/common/log.h"
#include "starboard/common/mutex.h"
#include "starboard/common/string.h"
#include "starboard/event.h"
#include "starboard/shared/starboard/audio_sink/audio_sink_internal.h"

namespace starboard {
namespace android {
namespace shared {

namespace {
  enum {
    kLooperIdAndroidCommand,
    kLooperIdAndroidInput,
    kLooperIdKeyboardInject,
  };

  const char* AndroidCommandName(
      ApplicationAndroid::AndroidCommand::CommandType type) {
    switch (type) {
      case ApplicationAndroid::AndroidCommand::kUndefined:
        return "Undefined";
      case ApplicationAndroid::AndroidCommand::kStart:
        return "Start";
      case ApplicationAndroid::AndroidCommand::kResume:
        return "Resume";
      case ApplicationAndroid::AndroidCommand::kPause:
        return "Pause";
      case ApplicationAndroid::AndroidCommand::kStop:
        return "Stop";
      case ApplicationAndroid::AndroidCommand::kInputQueueChanged:
        return "InputQueueChanged";
      case ApplicationAndroid::AndroidCommand::kNativeWindowCreated:
        return "NativeWindowCreated";
      case ApplicationAndroid::AndroidCommand::kNativeWindowDestroyed:
        return "NativeWindowDestroyed";
      case ApplicationAndroid::AndroidCommand::kWindowFocusGained:
        return "WindowFocusGained";
      case ApplicationAndroid::AndroidCommand::kWindowFocusLost:
        return "WindowFocusLost";
      default:
        return "unknown";
    }
  }
}  // namespace

// "using" doesn't work with class members, so make a local convenience type.
typedef ::starboard::shared::starboard::Application::Event Event;

ApplicationAndroid::ApplicationAndroid(ALooper* looper)
    : looper_(looper),
      native_window_(NULL),
      input_queue_(NULL),
      android_command_readfd_(-1),
      android_command_writefd_(-1),
      keyboard_inject_readfd_(-1),
      keyboard_inject_writefd_(-1),
      android_command_condition_(android_command_mutex_),
      activity_state_(AndroidCommand::kUndefined),
      window_(kSbWindowInvalid),
      last_is_accessibility_high_contrast_text_enabled_(false) {

  // Initialize Time Zone early so that local time works correctly.
  // Called once here to help SbTimeZoneGet*Name()
  tzset();

  // Initialize Android asset access early so that ICU can load its tables
  // from the assets. The use ICU is used in our logging.
  SbFileAndroidInitialize();

  int pipefd[2];
  int err;

  err = pipe(pipefd);
  SB_CHECK(err >= 0) << "pipe errno is:" << errno;
  android_command_readfd_ = pipefd[0];
  android_command_writefd_ = pipefd[1];
  ALooper_addFd(looper_, android_command_readfd_, kLooperIdAndroidCommand,
                ALOOPER_EVENT_INPUT, NULL, NULL);

  err = pipe(pipefd);
  SB_CHECK(err >= 0) << "pipe errno is:" << errno;
  keyboard_inject_readfd_ = pipefd[0];
  keyboard_inject_writefd_ = pipefd[1];
  ALooper_addFd(looper_, keyboard_inject_readfd_, kLooperIdKeyboardInject,
                ALOOPER_EVENT_INPUT, NULL, NULL);
}

ApplicationAndroid::~ApplicationAndroid() {
  ALooper_removeFd(looper_, android_command_readfd_);
  close(android_command_readfd_);
  close(android_command_writefd_);

  ALooper_removeFd(looper_, keyboard_inject_readfd_);
  close(keyboard_inject_readfd_);
  close(keyboard_inject_writefd_);
}

void ApplicationAndroid::Initialize() {
  SbAudioSinkPrivate::Initialize();
}

void ApplicationAndroid::Teardown() {
  SbAudioSinkPrivate::TearDown();
  SbFileAndroidTeardown();
}

SbWindow ApplicationAndroid::CreateWindow(const SbWindowOptions* options) {
  SB_UNREFERENCED_PARAMETER(options);
  if (SbWindowIsValid(window_)) {
    return kSbWindowInvalid;
  }
  window_ = new SbWindowPrivate;
  window_->native_window = native_window_;
  input_events_generator_.reset(new InputEventsGenerator(window_));
  return window_;
}

bool ApplicationAndroid::DestroyWindow(SbWindow window) {
  if (!SbWindowIsValid(window)) {
    return false;
  }

  input_events_generator_.reset();

  SB_DCHECK(window == window_);
  delete window_;
  window_ = kSbWindowInvalid;
  return true;
}

Event* ApplicationAndroid::WaitForSystemEventWithTimeout(SbTime time) {
  // Convert from microseconds to milliseconds, taking the ceiling value.
  // If we take the floor, or round, then we end up busy looping every time
  // the next event time is less than one millisecond.
  int timeout_millis = (time + kSbTimeMillisecond - 1) / kSbTimeMillisecond;
  int looper_events;
  int ident = ALooper_pollAll(timeout_millis, NULL, &looper_events, NULL);
  switch (ident) {
    case kLooperIdAndroidCommand:
      ProcessAndroidCommand();
      break;
    case kLooperIdAndroidInput:
      ProcessAndroidInput();
      break;
    case kLooperIdKeyboardInject:
      ProcessKeyboardInject();
      break;
  }

  // Always return NULL since we already dispatched our own system events.
  return NULL;
}

void ApplicationAndroid::WakeSystemEventWait() {
  ALooper_wake(looper_);
}

void ApplicationAndroid::OnResume() {
  JniEnvExt* env = JniEnvExt::Get();
  env->CallStarboardVoidMethodOrAbort("beforeStartOrResume", "()V");
}

void ApplicationAndroid::ProcessAndroidCommand() {
  JniEnvExt* env = JniEnvExt::Get();
  AndroidCommand cmd;
  int err = read(android_command_readfd_, &cmd, sizeof(cmd));
  SB_DCHECK(err >= 0) << "Command read failed. errno=" << errno;

  SB_LOG(INFO) << "Android command: " << AndroidCommandName(cmd.type);

  // The activity state to which we should sync the starboard state.
  AndroidCommand::CommandType sync_state = AndroidCommand::kUndefined;

  switch (cmd.type) {
    case AndroidCommand::kUndefined:
      break;

    case AndroidCommand::kInputQueueChanged: {
      ScopedLock lock(android_command_mutex_);
      if (input_queue_) {
        AInputQueue_detachLooper(input_queue_);
      }
      input_queue_ = static_cast<AInputQueue*>(cmd.data);
      if (input_queue_) {
        AInputQueue_attachLooper(input_queue_, looper_, kLooperIdAndroidInput,
                                 NULL, NULL);
      }
      // Now that we've swapped our use of the input queue, signal that the
      // Android UI thread can continue.
      android_command_condition_.Signal();
      break;
    }

    // Starboard resume/suspend is tied to the UI window being created/destroyed
    // (rather than to the Activity lifecycle) since Cobalt can't do anything at
    // all if it doesn't have a window surface to draw on.
    case AndroidCommand::kNativeWindowCreated:
      {
        ScopedLock lock(android_command_mutex_);
        native_window_ = static_cast<ANativeWindow*>(cmd.data);
        if (window_) {
          window_->native_window = native_window_;
        }
        // Now that we have the window, signal that the Android UI thread can
        // continue, before we start or resume the Starboard app.
        android_command_condition_.Signal();
      }
      if (state() == kStateUnstarted) {
        // This is the initial launch, so we have to start Cobalt now that we
        // have a window.
        env->CallStarboardVoidMethodOrAbort("beforeStartOrResume", "()V");
        DispatchStart();
      } else {
        // Now that we got a window back, change the command for the switch
        // below to sync up with the current activity lifecycle.
        sync_state = activity_state_;
      }
      break;
    case AndroidCommand::kNativeWindowDestroyed:
      // No need to JNI call StarboardBridge.beforeSuspend() since we did it
      // early in SendAndroidCommand().
      {
        ScopedLock lock(android_command_mutex_);
        // Cobalt can't keep running without a window, even if the Activity
        // hasn't stopped yet. DispatchAndDelete() will inject events as needed
        // if we're not already paused.
        DispatchAndDelete(new Event(kSbEventTypeSuspend, NULL, NULL));
        if (window_) {
          window_->native_window = NULL;
        }
        native_window_ = NULL;
        // Now that we've suspended the Starboard app, and let go of the window,
        // signal that the Android UI thread can continue.
        android_command_condition_.Signal();
      }
      break;

    case AndroidCommand::kWindowFocusLost:
      break;
    case AndroidCommand::kWindowFocusGained: {
      // Android does not have a publicly-exposed way to
      // register for high-contrast text settings changed events.
      // We assume that it can only change when our focus changes
      // (because the user exits and enters the app) so we check
      // for changes here.
      SbAccessibilityDisplaySettings settings;
      SbMemorySet(&settings, 0, sizeof(settings));
      if (!SbAccessibilityGetDisplaySettings(&settings)) {
        break;
      }

      bool enabled = settings.has_high_contrast_text_setting &&
          settings.is_high_contrast_text_enabled;

      if (enabled != last_is_accessibility_high_contrast_text_enabled_) {
        DispatchAndDelete(new Event(
            kSbEventTypeAccessiblitySettingsChanged, NULL, NULL));
      }
      last_is_accessibility_high_contrast_text_enabled_ = enabled;
      break;
    }

    // Remember the Android activity state to sync to when we have a window.
    case AndroidCommand::kStart:
    case AndroidCommand::kResume:
    case AndroidCommand::kPause:
    case AndroidCommand::kStop:
      sync_state = activity_state_ = cmd.type;
      break;
  }

  // If there's a window, sync the app state to the Activity lifecycle, letting
  // DispatchAndDelete() inject events as needed if we missed a state.
  if (native_window_) {
    switch (sync_state) {
      case AndroidCommand::kStart:
        DispatchAndDelete(new Event(kSbEventTypeResume, NULL, NULL));
        break;
      case AndroidCommand::kResume:
        DispatchAndDelete(new Event(kSbEventTypeUnpause, NULL, NULL));
        break;
      case AndroidCommand::kPause:
        DispatchAndDelete(new Event(kSbEventTypePause, NULL, NULL));
        break;
      case AndroidCommand::kStop:
        if (state() != kStateSuspended) {
          // We usually suspend when losing the window above, but if the window
          // wasn't destroyed (e.g. when Daydream starts) then we still have to
          // suspend when the Activity is stopped.
          env->CallStarboardVoidMethodOrAbort("beforeSuspend", "()V");
          DispatchAndDelete(new Event(kSbEventTypeSuspend, NULL, NULL));
        }
        break;
      default:
        break;
    }
  }
}

void ApplicationAndroid::SendAndroidCommand(AndroidCommand::CommandType type,
                                            void* data) {
  SB_LOG(INFO) << "Send Android command: " << AndroidCommandName(type);
  if (type == AndroidCommand::kNativeWindowDestroyed) {
    // When this command is processed it will suspend Cobalt, so make the JNI
    // call to StarboardBridge.beforeSuspend() early while still here on the
    // Android main thread. This lets the MediaSession get released now without
    // having to wait to bounce between threads.
    JniEnvExt* env = JniEnvExt::Get();
    env->CallStarboardVoidMethodOrAbort("beforeSuspend", "()V");
  }
  AndroidCommand cmd {type, data};
  ScopedLock lock(android_command_mutex_);
  write(android_command_writefd_, &cmd, sizeof(cmd));
  // Synchronization only necessary when managing resources.
  switch (type) {
    case AndroidCommand::kInputQueueChanged:
      while (input_queue_ != data) {
        android_command_condition_.Wait();
      }
      break;
    case AndroidCommand::kNativeWindowCreated:
    case AndroidCommand::kNativeWindowDestroyed:
      while (native_window_ != data) {
        android_command_condition_.Wait();
      }
      break;
    default:
      break;
  }
}

void ApplicationAndroid::ProcessAndroidInput() {
  AInputEvent* android_event = NULL;
  while (AInputQueue_getEvent(input_queue_, &android_event) >= 0) {
    SB_LOG(INFO) << "Android input: type="
                 << AInputEvent_getType(android_event);
    if (AInputQueue_preDispatchEvent(input_queue_, android_event)) {
        continue;
    }
    if (!input_events_generator_) {
      SB_DLOG(WARNING) << "Android input event ignored without an SbWindow.";
      AInputQueue_finishEvent(input_queue_, android_event, false);
      continue;
    }
    InputEventsGenerator::Events app_events;
    bool handled = input_events_generator_->CreateInputEventsFromAndroidEvent(
        android_event, &app_events);
    for (int i = 0; i < app_events.size(); ++i) {
      DispatchAndDelete(app_events[i].release());
    }
    AInputQueue_finishEvent(input_queue_, android_event, handled);
  }
}

void ApplicationAndroid::ProcessKeyboardInject() {
  SbKey key;
  int err = read(keyboard_inject_readfd_, &key, sizeof(key));
  SB_DCHECK(err >= 0) << "Keyboard inject read failed: errno=" << errno;
  SB_LOG(INFO) << "Keyboard inject: " << key;
  if (!input_events_generator_) {
    SB_DLOG(WARNING) << "Injected input event ignored without an SbWindow.";
    return;
  }
  InputEventsGenerator::Events app_events;
  input_events_generator_->CreateInputEventsFromSbKey(key, &app_events);
  for (int i = 0; i < app_events.size(); ++i) {
    DispatchAndDelete(app_events[i].release());
  }
}

void ApplicationAndroid::SendKeyboardInject(SbKey key) {
  write(keyboard_inject_writefd_, &key, sizeof(key));
}

extern "C" SB_EXPORT_PLATFORM void
Java_dev_cobalt_coat_CobaltA11yHelper_nativeInjectKeyEvent(JNIEnv* env,
                                                           jobject unused_clazz,
                                                           jint key) {
  ApplicationAndroid::Get()->SendKeyboardInject(static_cast<SbKey>(key));
}

extern "C" SB_EXPORT_PLATFORM jboolean
Java_dev_cobalt_coat_KeyboardInputConnection_nativeHasOnScreenKeyboard(
    JniEnvExt* env,
    jobject unused_this) {
#if SB_HAS(ON_SCREEN_KEYBOARD)
  return JNI_TRUE;
#else   // SB_HAS(ON_SCREEN_KEYBOARD)
  return JNI_FALSE;
#endif  // SB_HAS(ON_SCREEN_KEYBOARD)
}

#if SB_HAS(ON_SCREEN_KEYBOARD)

void ApplicationAndroid::SbWindowShowOnScreenKeyboard(SbWindow window,
                                                      const char* input_text,
                                                      int ticket) {
  JniEnvExt* env = JniEnvExt::Get();
  jobject j_keyboard_editor = env->CallStarboardObjectMethodOrAbort(
      "getKeyboardEditor", "()Ldev/cobalt/coat/KeyboardEditor;");
  env->CallVoidMethodOrAbort(j_keyboard_editor, "showKeyboard", "()V");
  int* data = new int;
  *data = ticket;
  Inject(new Event(kSbEventTypeOnScreenKeyboardShown, data,
                   &DeleteDestructor<int>));
  return;
}

void ApplicationAndroid::SbWindowHideOnScreenKeyboard(SbWindow window,
                                                      int ticket) {
  JniEnvExt* env = JniEnvExt::Get();
  jobject j_keyboard_editor = env->CallStarboardObjectMethodOrAbort(
      "getKeyboardEditor", "()Ldev/cobalt/coat/KeyboardEditor;");
  env->CallVoidMethodOrAbort(j_keyboard_editor, "hideKeyboard", "()V");
  int* data = new int;
  *data = ticket;
  Inject(new Event(kSbEventTypeOnScreenKeyboardHidden, data,
                   &DeleteDestructor<int>));
  return;
}

void ApplicationAndroid::SbWindowUpdateOnScreenKeyboardSuggestions(
    SbWindow window,
    const std::vector<std::string>& suggestions,
    int ticket) {
  JniEnvExt* env = JniEnvExt::Get();
  jobjectArray completions = env->NewObjectArray(
      suggestions.size(),
      env->FindClass("android/view/inputmethod/CompletionInfo"), 0);
  jstring str;
  jobject j_completion_info;
  for (size_t i = 0; i < suggestions.size(); i++) {
    str = env->NewStringUTF(suggestions[i].c_str());
    j_completion_info =
        env->NewObjectOrAbort("android/view/inputmethod/CompletionInfo",
                              "(JILjava/lang/CharSequence;)V", i, i, str);
    env->SetObjectArrayElement(completions, i, j_completion_info);
  }
  jobject j_keyboard_editor = env->CallStarboardObjectMethodOrAbort(
      "getKeyboardEditor", "()Ldev/cobalt/coat/KeyboardEditor;");
  env->CallVoidMethodOrAbort(j_keyboard_editor, "updateCustomCompletions",
                             "([Landroid/view/inputmethod/CompletionInfo;)V",
                             completions);
  int* data = new int;
  *data = ticket;
  Inject(new Event(kSbEventTypeOnScreenKeyboardSuggestionsUpdated, data,
                   &DeleteDestructor<int>));
  return;
}

extern "C" SB_EXPORT_PLATFORM void
Java_dev_cobalt_coat_KeyboardInputConnection_nativeSendText(
    JniEnvExt* env,
    jobject unused_clazz,
    jstring text,
    jboolean is_composing) {
  if (text) {
    std::string utf_str = env->GetStringStandardUTFOrAbort(text);
    ApplicationAndroid::Get()->SbWindowSendInputEvent(utf_str.c_str(),
                                                      is_composing);
  }
}

void DeleteSbInputDataWithText(void* ptr) {
  SbInputData* data = static_cast<SbInputData*>(ptr);
  const char* input_text = data->input_text;
  data->input_text = NULL;
  delete input_text;
  ApplicationAndroid::DeleteDestructor<SbInputData>(ptr);
}

void ApplicationAndroid::SbWindowSendInputEvent(const char* input_text,
                                                bool is_composing) {
  char* text = SbStringDuplicate(input_text);
  SbInputData* data = new SbInputData();
  SbMemorySet(data, 0, sizeof(*data));
  data->window = window_;
  data->type = kSbInputEventTypeInput;
  data->device_type = kSbInputDeviceTypeOnScreenKeyboard;
  data->input_text = text;
  data->is_composing = is_composing;
  Inject(new Event(kSbEventTypeInput, data, &DeleteSbInputDataWithText));
  return;
}

#endif  // SB_HAS(ON_SCREEN_KEYBOARD)

bool ApplicationAndroid::OnSearchRequested() {
  for (int i = 0; i < 2; i++) {
    SbInputData* data = new SbInputData();
    SbMemorySet(data, 0, sizeof(*data));
    data->window = window_;
    data->key = kSbKeyBrowserSearch;
    data->type = (i == 0) ? kSbInputEventTypePress : kSbInputEventTypeUnpress;
    Inject(new Event(kSbEventTypeInput, data, &DeleteDestructor<SbInputData>));
  }
  return true;
}

extern "C" SB_EXPORT_PLATFORM
jboolean Java_dev_cobalt_coat_StarboardBridge_nativeOnSearchRequested(
    JniEnvExt* env, jobject unused_this) {
  return ApplicationAndroid::Get()->OnSearchRequested();
}

void ApplicationAndroid::HandleDeepLink(const char* link_url) {
  if (link_url == NULL || link_url[0] == '\0') {
    return;
  }
  char* deep_link = SbStringDuplicate(link_url);
  SB_DCHECK(deep_link);
  Inject(new Event(kSbEventTypeLink, deep_link, SbMemoryDeallocate));
}

extern "C" SB_EXPORT_PLATFORM
void Java_dev_cobalt_coat_StarboardBridge_nativeHandleDeepLink(
    JniEnvExt* env, jobject unused_this, jstring j_url) {
  if (j_url) {
    std::string utf_str = env->GetStringStandardUTFOrAbort(j_url);
    ApplicationAndroid::Get()->HandleDeepLink(utf_str.c_str());
  }
}

extern "C" SB_EXPORT_PLATFORM
void Java_dev_cobalt_coat_StarboardBridge_nativeStopApp(
    JniEnvExt* env, jobject unused_this, jint error_level) {
  ApplicationAndroid::Get()->Stop(error_level);
}

}  // namespace shared
}  // namespace android
}  // namespace starboard
