// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v10.1.6), do not edit directly.
// See also: https://pub.dev/packages/pigeon

#undef _HAS_EXCEPTIONS

#include "messages.h"

#include <flutter/basic_message_channel.h>
#include <flutter/binary_messenger.h>
#include <flutter/encodable_value.h>
#include <flutter/method_call.h>
#include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h>

#include <optional>
#include <string>

#include "plugins/common/common.h"

namespace url_launcher_linux {
using flutter::BasicMessageChannel;
using flutter::CustomEncodableValue;
using flutter::EncodableList;
using flutter::EncodableMap;
using flutter::EncodableValue;

// Sets up an instance of `UrlLauncherApi` to handle messages through the
// `binary_messenger`.
void UrlLauncherApi::SetUp(flutter::BinaryMessenger* binary_messenger,
                           UrlLauncherApi* api) {
  {
    const auto channel = std::make_unique<flutter::MethodChannel<>>(
        binary_messenger, "plugins.flutter.io/url_launcher_linux",
        &flutter::StandardMethodCodec::GetInstance());
    if (api != nullptr) {
      channel->SetMethodCallHandler(
          [api](const flutter::MethodCall<>& call,
                const std::unique_ptr<flutter::MethodResult<>>& result) {
            SPDLOG_DEBUG("[url_launcher] {}", call.method_name());
            if ("closeWebView" == call.method_name()) {
              result->Success(flutter::EncodableValue(true));
            } else if ("canLaunch" == call.method_name()) {
              if (std::holds_alternative<std::string>(*call.arguments())) {
                const auto& value = std::get<std::string>(*call.arguments());
                spdlog::debug("[url_launcher] canLaunch: {}", value);
                if (const ErrorOr<bool> output = api->CanLaunchUrl(value);
                    output.has_error()) {
                  result->Error(output.error().code(),
                                output.error().message());
                  return;
                }
                result->Success(flutter::EncodableValue(true));
              } else if (std::holds_alternative<EncodableMap>(
                             *call.arguments())) {
                const auto& args = std::get_if<EncodableMap>(call.arguments());
                for (const auto& [fst, snd] : *args) {
                  if (std::holds_alternative<std::string>(fst) &&
                      std::holds_alternative<std::string>(snd)) {
                    auto key = std::get<std::string>(fst);
                    auto value = std::get<std::string>(snd);
                    if (key == "url") {
                      if (const ErrorOr<bool> output = api->CanLaunchUrl(value);
                          output.has_error()) {
                        result->Error(output.error().code(),
                                      output.error().message());
                        return;
                      }
                      result->Success(flutter::EncodableValue(true));
                    } else {
                      result->NotImplemented();
                    }
                  }
                  break;
                }
              }
            } else if ("launch" == call.method_name()) {
              const auto& arg = *call.arguments();
              plugin_common::Encodable::PrintFlutterEncodableValue("launch",
                                                                   arg);
              if (std::holds_alternative<std::string>(arg)) {
                const auto& value = std::get<std::string>(arg);
                spdlog::debug("[url_launcher] launch: {}", value);
                const std::optional<FlutterError> output =
                    api->LaunchUrl(value);
                if (output.has_value()) {
                  result->Error(output->code(), output->message(),
                                output->details());
                  return;
                }
              } else if (std::holds_alternative<EncodableMap>(arg)) {
                const auto& args = std::get<EncodableMap>(arg);
                std::string url;
                bool enableJavaScript{};
                bool enableDomStorage{};
                bool universalLinksOnly{};
                EncodableMap headers{};
                for (const auto& [fst, snd] : args) {
                  if (std::holds_alternative<std::string>(fst) &&
                      std::holds_alternative<std::string>(snd)) {
                    auto key = std::get<std::string>(fst);
                    auto value = std::get<std::string>(snd);
                    if (key == "url") {
                      url = value;
                    }
                  } else if (std::holds_alternative<std::string>(fst) &&
                             std::holds_alternative<bool>(snd)) {
                    auto key = std::get<std::string>(fst);
                    if (key == "enableJavaScript") {
                      enableJavaScript = std::get<bool>(snd);
                    } else if (key == "enableDomStorage") {
                      enableDomStorage = std::get<bool>(snd);
                    } else if (key == "universalLinksOnly") {
                      universalLinksOnly = std::get<bool>(snd);
                    } else if (std::holds_alternative<std::string>(fst) &&
                               std::holds_alternative<EncodableMap>(snd)) {
                      key = std::get<std::string>(fst);
                      auto map = std::get<EncodableMap>(snd);
                      if (key == "headers") {
                        for (const auto& [fst, snd] : map) {
                          auto header_key = std::get<std::string>(fst);
                          auto header_value = std::get<std::string>(snd);
                          SPDLOG_DEBUG("[url_launcher] {}={}", header_key,
                                       header_value);
                        }
                      } else {
                        plugin_common::Encodable::PrintFlutterEncodableMap(
                            key.c_str(), map);
                      }
                    }
                  }
                }
                spdlog::debug(
                    "[url_launcher] url: {}, enableJavaScript: {}, "
                    "enableDomStorage: {}, universalLinksOnly: {}",
                    url, enableJavaScript, enableDomStorage,
                    universalLinksOnly);
                if (const std::optional<FlutterError> output =
                        api->LaunchUrl(url);
                    output.has_value()) {
                  result->Error(output->code(), output->message(),
                                output->details());
                  return;
                }
              }
              result->Success(flutter::EncodableValue(true));
            } else {
              result->NotImplemented();
            }
          });
    }
  }
}

EncodableValue UrlLauncherApi::WrapError(const std::string_view error_message) {
  return EncodableValue(
      EncodableList{EncodableValue(std::string(error_message)),
                    EncodableValue("Error"), EncodableValue()});
}

EncodableValue UrlLauncherApi::WrapError(const FlutterError& error) {
  return EncodableValue(EncodableList{EncodableValue(error.code()),
                                      EncodableValue(error.message()),
                                      error.details()});
}

}  // namespace url_launcher_linux
