// Copyright 2021 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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 <array>
#include <span>
#include <string_view>

#include "pw_board_led/led.h"
#include "pw_hdlc/encoder.h"
#include "pw_hdlc/rpc_channel.h"
#include "pw_hdlc/rpc_packets.h"
#include "pw_log/log.h"
#include "pw_rpc/echo_service_nanopb.h"
#include "pw_rpc/server.h"
#include "pw_spin_delay/delay.h"
#include "pw_stream/sys_io_stream.h"
#include "remoticon/remoticon_service_nanopb.h"

// ------------------- superloop data -------------------
// This is some "application" state that eventually exported by RPCs.

unsigned superloop_iterations;

// ------------------- pw_rpc subsystem setup -------------------
// There are multiple ways to plumb pw_rpc in your product. In the future,
// Pigweed may offer an optional pre-canned setup; but for now, you must
// manually snap together the modular pieces.
//
// The RPC system in this code is layered as:
//
//   UART --> pw_sys_io ------> hdlc -------> pw_rpc
//   (phy)                   (transport)
//
// HDLC converts the raw UART/serial byte stream into a packet stream. Then RPC
// operates at the packet level.
//
// This is just one way to configure pw_rpc, which is designed to be flexible
// and work over wh atever physical or logical transport you have available.

constexpr size_t kMaxTransmissionUnit = 256;  // bytes

// Used to write HDLC data to pw::sys_io. This is an implementation of the
// pw::stream::Stream interface.
pw::stream::SysIoWriter sys_io_writer;

// Set up the output channel for the pw_rpc server to use. This one happens to
// implement the packet in / packet out with HDLC. pw_rpc can use any
// ChannelOptput implementation, including custom ones for your product.
pw::hdlc::RpcChannelOutputBuffer<kMaxTransmissionUnit> hdlc_channel_output(
    sys_io_writer, pw::hdlc::kDefaultRpcAddress, "HDLC channel");

// A pw::rpc::Server can have multiple channels (e.g. a UART and a BLE
// connection). In this case, there is only one (HDLC over UART).
pw::rpc::Channel channels[] = {
    pw::rpc::Channel::Create<1>(&hdlc_channel_output)};

// Declare the pw_rpc server with the HDLC channel.
pw::rpc::Server server(channels);

// Declare a buffer for decoding incoming HDLC frames.
std::array<std::byte, kMaxTransmissionUnit> input_buffer;

// Decoder object consumes bytes and return if a HDLC packet was completed.
pw::hdlc::Decoder hdlc_decoder(input_buffer);

// ------------------- pw_rpc service registration  -------------------
pw::rpc::EchoService echo_service;
remoticon::SuperloopService superloop_service(superloop_iterations);

// TODO FOR WORKSHOP: Declare your service object here!

void RegisterServices() {
  server.RegisterService(echo_service);
  server.RegisterService(superloop_service);
  // TODO FOR WORKSHOP: Register your service here!
}

// ------------------- pw_rpc  -------------------

constexpr unsigned kHdlcChannelForRpc = pw::hdlc::kDefaultRpcAddress;
constexpr unsigned kHdlcChannelForLogs = 1;

void ParseByteFromUartAndHandleRpcs() {
  // Read a byte from the UART if one is available; if not, bail.
  std::byte data;
  if (!pw::sys_io::TryReadByte(&data).ok()) {
    return;
  }

  // Byte received. Send the byte to the HDLC decoder; see if a packet finished.
  auto result = hdlc_decoder.Process(data);

  // Packet didn't parse correctly, so ignore it. In production, this should
  // perhaps log or increment a metric (see pw_metric) to track bad packets.
  if (!result.ok()) {
    // POST-WORKSHOP EXERCISE: Add a tracking metric for bad packets, and
    // expose the metric via the pw_metric RPC service. This will require
    // making some metrics objects, incrementing them; then creating and
    // registering a metric RPC service.
    //
    // See https://pigweed.dev/pw_metric/
    //     https://pigweed.dev/pw_metric/#exporting-metrics
    return;
  }

  PW_LOG_INFO("Got complete HDLC packet");

  // A frame was completed.
  pw::hdlc::Frame& hdlc_frame = result.value();
  if (hdlc_frame.address() != kHdlcChannelForRpc) {
    // We ignore frames that are for unknown addresses, but you could put
    // some code here if you wanted to stream custom data from PC --> device.
    PW_LOG_WARN("Got packet with no destination; address: %llu",
                hdlc_frame.address());
    return;
  }

  // Packet was validated and correct (CRC, etc); so send it to the RPC server.
  // The RPC server may send response packets before returning from this call.
  server.ProcessPacket(hdlc_frame.data(), hdlc_channel_output);
}

// TODO FOR WORKSHOP: Add an RPC to change the blink time.
int state = 0;
int counter = 0;
// TODO FOR WORKSHOP: Change this value. 5M is good for Teensy 4.0; what value
// is good for the Discovery?
int counter_max = 5'000'000;

void Blink() {
  // Toggle the state if needed.
  counter += 1;
  // PW_LOG_INFO("Counter: %d", counter);
  if (counter < counter_max) {
    // Haven't hit a toggle event yet; bail.
    return;
  }
  state = 1 - state;
  counter = 0;

  if (state == 0) {
    PW_LOG_INFO("Blink High!");
    pw::board_led::TurnOn();
  } else {
    PW_LOG_INFO("Blink Low!");
    pw::board_led::TurnOff();
  }
}

// TODO FOR WORKSHOP: Why doesn't this work, when of Blink() above does?
void BlinkNoWorky() {
  PW_LOG_INFO("Blink High!");
  pw::board_led::TurnOn();
  pw::spin_delay::WaitMillis(1000);

  PW_LOG_INFO("Blink Low!");
  pw::board_led::TurnOff();
  pw::spin_delay::WaitMillis(1000);
}

int main() {
  pw::board_led::Init();

  PW_LOG_INFO("Registering pw_rpc services");
  RegisterServices();

  // Superloop!
  while (true) {
    // Toggle the LED if needed.
    Blink();
    // BlinkNoWorky();  // Pop quiz: This doesn't work. Why?

    // Examine incoming serial byte; if a packet finished, send it to RPC.
    ParseByteFromUartAndHandleRpcs();

    // Increment the number of iterations.
    superloop_iterations++;
  }

  return 0;
}
