// Copyright 2015 The Weave Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "examples/daemon/common/daemon.h"

#include <weave/device.h>

#include <base/bind.h>
#include <base/memory/weak_ptr.h>

namespace {

const char kTraits[] = R"({
  "onOff": {
    "commands": {
      "setConfig": {
        "minimalRole": "user",
        "parameters": {
          "state": {
            "type": "string",
            "enum": [ "on", "standby" ]
          }
        }
      }
    },
    "state": {
      "state": {
        "type": "string",
        "enum": [ "on", "standby" ]
      }
    }
  },
  "brightness": {
    "commands": {
      "setConfig": {
        "minimalRole": "user",
        "parameters": {
          "brightness": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          }
        }
      }
    },
    "state": { "brightness": { "type": "integer" } }
  },
  "colorXY": {
    "commands": {
      "setConfig": {
        "minimalRole": "user",
        "parameters": {
          "colorSetting": {
            "type": "object",
            "required": [
              "colorX",
              "colorY"
            ],
            "properties": {
              "colorX": {
                "type": "number",
                "minimum": 0.0,
                "maximum": 1.0
              },
              "colorY": {
                "type": "number",
                "minimum": 0.0,
                "maximum": 1.0
              }
            },
            "additionalProperties": false
          }
        }
      }
    },
    "state": {
      "colorSetting": {
        "properties": {
          "colorX": {
            "type": "number",
            "minimum": 0.0,
            "maximum": 1.0
          },
          "colorY": {
            "type": "number",
            "minimum": 0.0,
            "maximum": 1.0
          }
        }
      },
      "colorCapRed": {
        "properties": {
          "colorX": {
            "type": "number",
            "minimum": 0.0,
            "maximum": 1.0
          },
          "colorY": {
            "type": "number",
            "minimum": 0.0,
            "maximum": 1.0
          }
        }
      },
      "colorCapGreen": {
        "properties": {
          "colorX": {
            "type": "number",
            "minimum": 0.0,
            "maximum": 1.0
          },
          "colorY": {
            "type": "number",
            "minimum": 0.0,
            "maximum": 1.0
          }
        }
      },
      "colorCapBlue": {
        "properties": {
          "colorX": {
            "type": "number",
            "minimum": 0.0,
            "maximum": 1.0
          },
          "colorY": {
            "type": "number",
            "minimum": 0.0,
            "maximum": 1.0
          }
        }
      }
    }
  }
})";

const char kDefaultState[] = R"({
  "colorXY": {
    "colorSetting": {"colorX": 0, "colorY": 0},
    "colorCapRed":  {"colorX": 0.674, "colorY": 0.322},
    "colorCapGreen":{"colorX": 0.408, "colorY": 0.517},
    "colorCapBlue": {"colorX": 0.168, "colorY": 0.041}
  }
})";

const char kComponent[] = "light";

}  // anonymous namespace

// LightHandler is a command handler example that shows
// how to handle commands for a Weave light.
class LightHandler {
 public:
  LightHandler() = default;
  void Register(weave::Device* device) {
    device_ = device;

    device->AddTraitDefinitionsFromJson(kTraits);
    CHECK(device->AddComponent(kComponent, {"onOff", "brightness", "colorXY"},
                               nullptr));
    CHECK(
        device->SetStatePropertiesFromJson(kComponent, kDefaultState, nullptr));
    UpdateLightState();

    device->AddCommandHandler(kComponent, "onOff.setConfig",
                              base::Bind(&LightHandler::OnOnOffSetConfig,
                                         weak_ptr_factory_.GetWeakPtr()));
    device->AddCommandHandler(kComponent, "brightness.setConfig",
                              base::Bind(&LightHandler::OnBrightnessSetConfig,
                                         weak_ptr_factory_.GetWeakPtr()));
    device->AddCommandHandler(kComponent, "colorXY.setConfig",
                              base::Bind(&LightHandler::OnColorXYSetConfig,
                                         weak_ptr_factory_.GetWeakPtr()));
  }

 private:
  void OnBrightnessSetConfig(const std::weak_ptr<weave::Command>& command) {
    auto cmd = command.lock();
    if (!cmd)
      return;
    LOG(INFO) << "received command: " << cmd->GetName();
    const auto& params = cmd->GetParameters();
    int32_t brightness_value = 0;
    if (params.GetInteger("brightness", &brightness_value)) {
      // Display this command in terminal.
      LOG(INFO) << cmd->GetName() << " brightness: " << brightness_value;

      if (brightness_state_ != brightness_value) {
        brightness_state_ = brightness_value;
        UpdateLightState();
      }
      cmd->Complete({}, nullptr);
      return;
    }
    weave::ErrorPtr error;
    weave::Error::AddTo(&error, FROM_HERE, "example", "invalid_parameter_value",
                        "Invalid parameters");
    cmd->Abort(error.get(), nullptr);
  }

  void OnOnOffSetConfig(const std::weak_ptr<weave::Command>& command) {
    auto cmd = command.lock();
    if (!cmd)
      return;
    LOG(INFO) << "received command: " << cmd->GetName();
    const auto& params = cmd->GetParameters();
    std::string requested_state;
    if (params.GetString("state", &requested_state)) {
      LOG(INFO) << cmd->GetName() << " state: " << requested_state;

      bool new_light_status = requested_state == "on";
      if (new_light_status != light_status_) {
        light_status_ = new_light_status;

        LOG(INFO) << "Light is now: " << (light_status_ ? "ON" : "OFF");
        UpdateLightState();
      }
      cmd->Complete({}, nullptr);
      return;
    }
    weave::ErrorPtr error;
    weave::Error::AddTo(&error, FROM_HERE, "example", "invalid_parameter_value",
                        "Invalid parameters");
    cmd->Abort(error.get(), nullptr);
  }

  void OnColorXYSetConfig(const std::weak_ptr<weave::Command>& command) {
    auto cmd = command.lock();
    if (!cmd)
      return;
    LOG(INFO) << "received command: " << cmd->GetName();
    const auto& params = cmd->GetParameters();
    const base::DictionaryValue* colorXY = nullptr;
    if (params.GetDictionary("colorSetting", &colorXY)) {
      bool updateState = false;
      double X = 0.0;
      double Y = 0.0;
      if (colorXY->GetDouble("colorX", &X)) {
        color_X_ = X;
        updateState = true;
      }

      if (colorXY->GetDouble("colorY", &Y)) {
        color_Y_ = Y;
        updateState = true;
      }

      if (updateState)
        UpdateLightState();

      cmd->Complete({}, nullptr);
      return;
    }

    weave::ErrorPtr error;
    weave::Error::AddTo(&error, FROM_HERE, "example", "invalid_parameter_value",
                        "Invalid parameters");
    cmd->Abort(error.get(), nullptr);
  }

  void UpdateLightState() {
    base::DictionaryValue state;
    state.SetString("onOff.state", light_status_ ? "on" : "standby");
    state.SetInteger("brightness.brightness", brightness_state_);

    std::unique_ptr<base::DictionaryValue> colorXY(new base::DictionaryValue());
    colorXY->SetDouble("colorX", color_X_);
    colorXY->SetDouble("colorY", color_Y_);
    state.Set("colorXY.colorSetting", colorXY.release());
    device_->SetStateProperties(kComponent, state, nullptr);
  }

  weave::Device* device_{nullptr};

  // Simulate the state of the light.
  bool light_status_{false};
  int32_t brightness_state_{0};
  double color_X_{0.0};
  double color_Y_{0.0};
  base::WeakPtrFactory<LightHandler> weak_ptr_factory_{this};
};

int main(int argc, char** argv) {
  Daemon::Options opts;
  opts.model_id_ = "AIAAA";
  if (!opts.Parse(argc, argv)) {
    Daemon::Options::ShowUsage(argv[0]);
    return 1;
  }
  Daemon daemon{opts};
  LightHandler handler;
  handler.Register(daemon.GetDevice());
  daemon.Run();
  return 0;
}
