// Copyright 2019 The Fuchsia 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 SRC_UI_LIGHT_DRIVERS_AML_LIGHT_AML_LIGHT_H_
#define SRC_UI_LIGHT_DRIVERS_AML_LIGHT_AML_LIGHT_H_

#include <fidl/fuchsia.hardware.gpio/cpp/wire.h>
#include <fidl/fuchsia.hardware.light/cpp/wire.h>
#include <fidl/fuchsia.hardware.pwm/cpp/wire.h>
#include <lib/ddk/debug.h>
#include <threads.h>

#include <optional>
#include <string>
#include <vector>

#include <ddktl/device.h>
#include <ddktl/protocol/empty-protocol.h>
#include <fbl/array.h>
#include <soc/aml-common/aml-pwm-regs.h>
namespace aml_light {

using fuchsia_hardware_light::Light;
using fuchsia_hardware_light::wire::Capability;
using fuchsia_hardware_light::wire::LightError;
using fuchsia_hardware_light::wire::Rgb;

class AmlLight;
using AmlLightType = ddk::Device<AmlLight, ddk::Messageable<Light>::Mixin>;

class LightDevice {
 public:
  LightDevice(std::string name, fidl::ClientEnd<fuchsia_hardware_gpio::Gpio> gpio,
              std::optional<fidl::WireSyncClient<fuchsia_hardware_pwm::Pwm>> pwm,
              zx::duration pwm_period)
      : name_(std::move(name)),
        gpio_(std::move(gpio)),
        pwm_(std::move(pwm)),
        pwm_period_(pwm_period) {}

  zx_status_t Init(bool init_on);

  const std::string& GetName() const { return name_; }
  Capability GetCapability() const {
    return pwm_.has_value() ? Capability::kBrightness : Capability::kSimple;
  }
  bool GetCurrentSimpleValue() const { return (value_ != 0); }
  zx_status_t SetSimpleValue(bool value);
  double GetCurrentBrightnessValue() const { return value_; }
  zx_status_t SetBrightnessValue(double value);

 private:
  std::string name_;
  fidl::WireSyncClient<fuchsia_hardware_gpio::Gpio> gpio_;
  std::optional<fidl::WireSyncClient<fuchsia_hardware_pwm::Pwm>> pwm_;

  double value_ = 0;
  const zx::duration pwm_period_;
};

class AmlLight : public AmlLightType, public ddk::EmptyProtocol<ZX_PROTOCOL_LIGHT> {
 public:
  explicit AmlLight(zx_device_t* parent) : AmlLightType(parent) {}

  static zx_status_t Create(void* ctx, zx_device_t* parent);

  // Device protocol implementation.
  void DdkRelease();

  // FIDL messages.
  void GetNumLights(GetNumLightsCompleter::Sync& completer) override;
  void GetNumLightGroups(GetNumLightGroupsCompleter::Sync& completer) override;
  void GetInfo(GetInfoRequestView request, GetInfoCompleter::Sync& completer) override;
  void GetCurrentSimpleValue(GetCurrentSimpleValueRequestView request,
                             GetCurrentSimpleValueCompleter::Sync& completer) override;
  void SetSimpleValue(SetSimpleValueRequestView request,
                      SetSimpleValueCompleter::Sync& completer) override;
  void GetCurrentBrightnessValue(GetCurrentBrightnessValueRequestView request,
                                 GetCurrentBrightnessValueCompleter::Sync& completer) override;
  void SetBrightnessValue(SetBrightnessValueRequestView request,
                          SetBrightnessValueCompleter::Sync& completer) override;
  void GetCurrentRgbValue(GetCurrentRgbValueRequestView request,
                          GetCurrentRgbValueCompleter::Sync& completer) override;
  void SetRgbValue(SetRgbValueRequestView request, SetRgbValueCompleter::Sync& completer) override;

  void GetGroupInfo(GetGroupInfoRequestView request,
                    GetGroupInfoCompleter::Sync& completer) override {
    completer.ReplyError(LightError::kNotSupported);
  }
  void GetGroupCurrentSimpleValue(GetGroupCurrentSimpleValueRequestView request,
                                  GetGroupCurrentSimpleValueCompleter::Sync& completer) override {
    completer.ReplyError(LightError::kNotSupported);
  }
  void SetGroupSimpleValue(SetGroupSimpleValueRequestView request,
                           SetGroupSimpleValueCompleter::Sync& completer) override {
    completer.ReplyError(LightError::kNotSupported);
  }
  void GetGroupCurrentBrightnessValue(
      GetGroupCurrentBrightnessValueRequestView request,
      GetGroupCurrentBrightnessValueCompleter::Sync& completer) override {
    completer.ReplyError(LightError::kNotSupported);
  }
  void SetGroupBrightnessValue(SetGroupBrightnessValueRequestView request,
                               SetGroupBrightnessValueCompleter::Sync& completer) override {
    completer.ReplyError(LightError::kNotSupported);
  }
  void GetGroupCurrentRgbValue(GetGroupCurrentRgbValueRequestView request,
                               GetGroupCurrentRgbValueCompleter::Sync& completer) override {
    completer.ReplyError(LightError::kNotSupported);
  }
  void SetGroupRgbValue(SetGroupRgbValueRequestView request,
                        SetGroupRgbValueCompleter::Sync& completer) override {
    completer.ReplyError(LightError::kNotSupported);
  }

 private:
  DISALLOW_COPY_ASSIGN_AND_MOVE(AmlLight);
  friend class FakeAmlLight;

  zx_status_t Init();

  static constexpr size_t kNameLength = ZX_MAX_NAME_LEN;

  std::vector<LightDevice> lights_;
};

}  // namespace aml_light

#endif  // SRC_UI_LIGHT_DRIVERS_AML_LIGHT_AML_LIGHT_H_
