// Copyright 2021 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/linux/shared/soft_mic_platform_service.h"

#include <memory>
#include <string>

#include "cobalt/extension/platform_service.h"
#include "starboard/common/log.h"
#include "starboard/common/string.h"
#include "starboard/configuration.h"
#include "starboard/shared/starboard/application.h"
#if SB_IS(EVERGREEN_COMPATIBLE)
#include "starboard/elf_loader/evergreen_config.h"
#endif  // SB_IS(EVERGREEN_COMPATIBLE)

typedef struct CobaltExtensionPlatformServicePrivate {
  void* context;
  ReceiveMessageCallback receive_callback;
} CobaltExtensionPlatformServicePrivate;

// Omit namespace linux due to symbol name conflict.
namespace starboard {
namespace shared {

namespace {

const char kGetMicSupport[] = "\"getMicSupport\"";
const char kNotifySearchActive[] = "\"notifySearchActive\"";
const char kNotifySearchInactive[] = "\"notifySearchInactive\"";
const char kHasHardMicSupport[] = "has_hard_mic_support";
const char kHasSoftMicSupport[] = "has_soft_mic_support";
const char kMicGesture[] = "mic_gesture";
const char kJSONTrue[] = "true";
const char kJSONFalse[] = "false";

bool Has(const char* name) {
  // Check if platform has service name.
  return strcmp(name, "com.google.youtube.tv.SoftMic") == 0;
}

CobaltExtensionPlatformService Open(void* context,
                                    const char* name,
                                    ReceiveMessageCallback receive_callback) {
  SB_DCHECK(context);

  CobaltExtensionPlatformService service;

  if (!Has(name)) {
    SB_LOG(ERROR) << "Open() service name does not exist: " << name;
    service = kCobaltExtensionPlatformServiceInvalid;
  } else {
    SB_LOG(INFO) << "Open() service created: " << name;
    service =
        new CobaltExtensionPlatformServicePrivate({context, receive_callback});
  }

#if SB_IS(EVERGREEN_COMPATIBLE)
  const bool is_evergreen = elf_loader::EvergreenConfig::GetInstance() != NULL;
#else
  const bool is_evergreen = false;
#endif  // SB_IS(EVERGREEN_COMPATIBLE)

  // The name parameter memory is allocated in h5vcc_platform_service::Open()
  // with new[] and must be deallocated here.
  // If we are in an Evergreen build, the name parameter must be deallocated
  // with SbMemoryDeallocate(), since new[] will map to SbMemoryAllocate()
  // in an Evergreen build.
  if (is_evergreen) {
    SbMemoryDeallocate((void*)name);  // NOLINT
  } else {
    delete[] name;
  }

  return service;
}

void Close(CobaltExtensionPlatformService service) {
  SB_LOG(INFO) << "Close() Service.";
  delete static_cast<CobaltExtensionPlatformServicePrivate*>(service);
}

void* Send(CobaltExtensionPlatformService service,
           void* data,
           uint64_t length,
           uint64_t* output_length,
           bool* invalid_state) {
  SB_DCHECK(service);
  SB_DCHECK(data);
  SB_DCHECK(output_length);

  // This bool flag is set to true if the data argument
  // is successfully parsed as a known web app request,
  // false otherwise. It is then sent as a synchronous
  // response to the web app indicating this success or
  // failure.
  auto valid_message_received = false;

  char message[length + 1];
  std::memcpy(message, data, length);
  message[length] = '\0';

  SB_LOG(INFO) << "Send() message: " << message;

  if (strcmp(message, kGetMicSupport) == 0) {
    // Process "getMicSupport" web app message.
    SB_LOG(INFO) << "Send() kGetMicSupport message received.";

    auto has_hard_mic = false;
    auto has_soft_mic = true;
    auto mic_gesture_hold = false;
    auto mic_gesture_tap = false;

#if !defined(COBALT_BUILD_TYPE_GOLD)
    using shared::starboard::Application;

    // Check for explicit true or false switch value for kHasHardMicSupport,
    // kHasSoftMicSupport, kMicGestureHold, and kMicGestureTap optional target
    // params. Use default values if none are set.
    auto command_line = Application::Get()->GetCommandLine();

    auto hard_mic_switch_value =
        command_line->GetSwitchValue(kHasHardMicSupport);
    if (hard_mic_switch_value == kJSONTrue) {
      has_hard_mic = true;
    } else if (hard_mic_switch_value == kJSONFalse) {
      has_hard_mic = false;
    }

    auto soft_mic_switch_value =
        command_line->GetSwitchValue(kHasSoftMicSupport);
    if (soft_mic_switch_value == kJSONTrue) {
      has_soft_mic = true;
    } else if (soft_mic_switch_value == kJSONFalse) {
      has_soft_mic = false;
    }

    auto mic_gesture_switch_value = command_line->GetSwitchValue(kMicGesture);
    mic_gesture_hold = mic_gesture_switch_value == "hold";
    mic_gesture_tap = mic_gesture_switch_value == "tap";
#endif  // !defined(COBALT_BUILD_TYPE_GOLD)

    auto mic_gesture = "null";
    if (mic_gesture_hold)
      mic_gesture = "\"HOLD\"";
    else if (mic_gesture_tap)
      mic_gesture = "\"TAP\"";

    auto response = FormatString(
        "{\"hasHardMicSupport\": %s, \"hasSoftMicSupport\": %s, "
        "\"micGesture\": %s}",
        (has_hard_mic ? kJSONTrue : kJSONFalse),
        (has_soft_mic ? kJSONTrue : kJSONFalse), mic_gesture);

    SB_LOG(INFO) << "Send() kGetMicSupport response: " << response;

    // Here we are synchronously calling the receive_callback() from within
    // Send() which is unnecessary. Implementations should prioritize
    // returning from Send() ASAP to avoid blocking the JavaScript thread.
    static_cast<CobaltExtensionPlatformServicePrivate*>(service)
        ->receive_callback(service->context,
                           static_cast<const void*>(response.c_str()),
                           response.length());

    valid_message_received = true;
  } else if (strcmp(message, kNotifySearchActive) == 0) {
    // Process "notifySearchActive" web app message.
    SB_LOG(INFO) << "Send() kNotifySearchActive message received";
    valid_message_received = true;
  } else if (strcmp(message, kNotifySearchInactive) == 0) {
    // Process "notifySearchInactive" web app message.
    SB_LOG(INFO) << "Send() kNotifySearchInactive message received";
    valid_message_received = true;
  }

  // Synchronous bool response to the web app confirming the message
  // has been successfully parsed by the platform. Response needs
  // to be allocated with SbMemoryAllocate() as the caller of Send()
  // in cobalt/h5vcc/h5vcc_platform_service.cc Send() uses
  // SbMemoryDeallocate().
  bool* ptr = reinterpret_cast<bool*>(SbMemoryAllocate(sizeof(bool)));
  *ptr = valid_message_received;
  *output_length = sizeof(bool);
  return static_cast<void*>(ptr);
}

const CobaltExtensionPlatformServiceApi kPlatformServiceApi = {
    kCobaltExtensionPlatformServiceName,
    1,  // API version that's implemented.
    &Has,
    &Open,
    &Close,
    &Send};

}  // namespace

const void* GetPlatformServiceApi() {
  return &kPlatformServiceApi;
}

}  // namespace shared
}  // namespace starboard
