text: /*
   * Copyright 2018-2020 Amazon.com, Inc. or its affiliates. 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.
   * A copy of the License is located at
   *
   *     http://aws.amazon.com/apache2.0/
   *
   * or in the "license" file accompanying this file. This file 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 "LocalMediaSourceDispatcher.h"
  
  #include <json-c/json.h>
  
  #include <aasb/Consts.h>
  
  #include "AlexaConsts.h"
  
  namespace agl {
  namespace dispatcher {
  namespace localmediasource {
  
  // Shortcut to reach logging level.
  using Level = agl::common::interfaces::ILogger::Level;
  
  // Namespaces.
  using namespace agl::common::interfaces;
  using namespace aasb::bridge;
  
  // Logging Tag for this file.
  static std::string TAG = "alexa::plugins::LocalMediaSourceDispatcher";
  
  // Name of the localmediasource capability
  static std::string VSHL_CAPABILITY_LOCAL_MEDIA_SOURCE = "localmediasource";
  
  // LocalMediaSource publish verb to notify vshl capabilities of new event/directive generated by Alexa.
  static std::string VSHL_CAPABILITY_VERB_LOCAL_MEDIA_SOURCE_PUBLISH = VSHL_CAPABILITY_LOCAL_MEDIA_SOURCE + "/publish";
  
  // LocalMediaSource subscribe verb to subscribe for vshl capabilities events from Apps.
  static std::string VSHL_CAPABILITY_VERB_LOCAL_MEDIA_SOURCE_SUBSCRIBE = VSHL_CAPABILITY_LOCAL_MEDIA_SOURCE + "/subscribe";
  
  std::shared_ptr<LocalMediaSourceDispatcher> LocalMediaSourceDispatcher::create(
      std::shared_ptr<ILogger> logger,
      std::shared_ptr<IAASBController> aasbController,
      std::shared_ptr<IAFBApi> api) {
  
      return std::shared_ptr<LocalMediaSourceDispatcher>(new LocalMediaSourceDispatcher(logger, aasbController, api));
  }
  
  LocalMediaSourceDispatcher::LocalMediaSourceDispatcher(
      std::shared_ptr<ILogger> logger,
      std::shared_ptr<IAASBController> aasbController,
      std::shared_ptr<IAFBApi> api) :
          m_logger(logger),
          m_aasbController(aasbController),
          m_api(api) {
  }
  
  void LocalMediaSourceDispatcher::onReceivedDirective(
      const std::string& action,
      const std::string& payload) {
  
      m_logger->log(Level::DEBUG, TAG, "Processing localmediasource directive: " + action);
  
      std::string vshlCapabilityAction = action;
  
      json_object* argsJ = json_object_new_object();
      json_object* actionJ = json_object_new_string(vshlCapabilityAction.c_str());
      json_object* payloadJ = json_object_new_string(payload.c_str());
      json_object_object_add(argsJ, agl::alexa::JSON_ATTR_ACTION.c_str(), actionJ);
      json_object_object_add(argsJ, agl::alexa::JSON_ATTR_PAYLOAD.c_str(), payloadJ);
  
      auto logger = m_logger;  // To capture it for the lambda.
      m_api->callAsync(
          agl::alexa::VSHL_CAPABILITIES_API_NAME,
          VSHL_CAPABILITY_VERB_LOCAL_MEDIA_SOURCE_PUBLISH,
          argsJ,
          [logger](json_object* result, const std::string err, const std::string info) {
              logger->log(Level::DEBUG, TAG, "LocalMediaSource publish completed err:" + err);
          });
  
      m_logger->log(Level::DEBUG, TAG, "LocalMediaSource action processing completed");
  }
  
  bool LocalMediaSourceDispatcher::subscribeToLocalMediaSourceEvents() {
      m_logger->log(Level::INFO, TAG, "Subscribing to localmediasource control capabilities");
  
      json_object *argsJ = json_object_new_object();
      json_object *actionsJ = json_object_new_array();
      json_object_array_add(actionsJ, json_object_new_string(aasb::bridge::ACTION_LOCAL_MEDIA_SOURCE_GET_STATE_RESPONSE.c_str()));
  
      json_object_object_add(argsJ, agl::alexa::JSON_ATTR_ACTIONS.c_str(), actionsJ);
  
      json_object* response = NULL;
      std::string error, info;
      int result = m_api->callSync(
          agl::alexa::VSHL_CAPABILITIES_API_NAME,
          VSHL_CAPABILITY_VERB_LOCAL_MEDIA_SOURCE_SUBSCRIBE,
          argsJ,
          &response,
          error,
          info);
      if (result != 0) {
          m_logger->log(Level::ERROR, TAG, "Failed to subscribe to localmediasource control capabilities. Error: " + error);
      }
  
      if (response != NULL) {
          json_object_put(response);
      }
  
      return result == 0;
  }
  
  void LocalMediaSourceDispatcher::onGetStateResponse(const std::string& payload) {
      m_aasbController->onReceivedEvent(
          TOPIC_LOCAL_MEDIA_SOURCE,
          ACTION_LOCAL_MEDIA_SOURCE_GET_STATE_RESPONSE,
          payload);
  }
  
  void LocalMediaSourceDispatcher::onPlayerEvent(const std::string& payload) {
      m_aasbController->onReceivedEvent(
          TOPIC_LOCAL_MEDIA_SOURCE,
          ACTION_LOCAL_MEDIA_SOURCE_PLAYER_EVENT,
          payload);
  }
  
  void LocalMediaSourceDispatcher::onPlayerError(const std::string& payload) {
      m_aasbController->onReceivedEvent(
          TOPIC_LOCAL_MEDIA_SOURCE,
          ACTION_LOCAL_MEDIA_SOURCE_PLAYER_ERROR,
          payload);
  }
  
  }  // namespace localmediasource
  }  // namespace dispatcher
  }  // namespace agl
  