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

#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_FUNCTIONS_H_
#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_FUNCTIONS_H_

#include <functional>
#include <string>

#include "method_result.h"

namespace flutter {

// Handler types for each of the MethodResult outcomes.
template <typename T>
using ResultHandlerSuccess = std::function<void(const T* result)>;
template <typename T>
using ResultHandlerError = std::function<void(const std::string& error_code,
                                              const std::string& error_message,
                                              const T* error_details)>;
template <typename T>
using ResultHandlerNotImplemented = std::function<void()>;

// An implementation of MethodResult that pass calls through to provided
// function objects, for ease of constructing one-off result handlers.
template <typename T>
class MethodResultFunctions : public MethodResult<T> {
 public:
  // Creates a result object that calls the provided functions for the
  // corresponding MethodResult outcomes.
  MethodResultFunctions(ResultHandlerSuccess<T> on_success,
                        ResultHandlerError<T> on_error,
                        ResultHandlerNotImplemented<T> on_not_implemented)
      : on_success_(on_success),
        on_error_(on_error),
        on_not_implemented_(on_not_implemented) {}

  virtual ~MethodResultFunctions() = default;

  // Prevent copying.
  MethodResultFunctions(MethodResultFunctions const&) = delete;
  MethodResultFunctions& operator=(MethodResultFunctions const&) = delete;

 protected:
  // |flutter::MethodResult|
  void SuccessInternal(const T* result) override {
    if (on_success_) {
      on_success_(result);
    }
  }

  // |flutter::MethodResult|
  void ErrorInternal(const std::string& error_code,
                     const std::string& error_message,
                     const T* error_details) override {
    if (on_error_) {
      on_error_(error_code, error_message, error_details);
    }
  }

  // |flutter::MethodResult|
  void NotImplementedInternal() override {
    if (on_not_implemented_) {
      on_not_implemented_();
    }
  }

 private:
  ResultHandlerSuccess<T> on_success_;
  ResultHandlerError<T> on_error_;
  ResultHandlerNotImplemented<T> on_not_implemented_;
};

}  // namespace flutter

#endif  // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_FUNCTIONS_H_
