/* Basic Multi Threading Arduino Example
   This example code is in the Public Domain (or CC0 licensed, at your option.)
   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
// Please read file README.md in the folder containing this example.

#include <Arduino.h>

SemaphoreHandle_t package_delivered_semaphore;

void delivery_truck_task(void *pvParameters) {
  int truck_number = (intptr_t)pvParameters;
  while (1) {
    // Notify the warehouse that a package has been delivered
    if (xSemaphoreGive(package_delivered_semaphore) == pdTRUE) {
      Serial.printf("Delivered by truck: %d\n", truck_number);
    } else {
      Serial.printf("Truck %d is idle\n", truck_number);
    }
    // Wait for some time
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
}

void warehouse_worker_task(void *pvParameters) {
  int worker_number = (intptr_t)pvParameters;
  while (1) {
    // Wait indefinitely for a package to be delivered
    if (xSemaphoreTake(package_delivered_semaphore, portMAX_DELAY) == pdTRUE) {
      Serial.printf("Received by worker: %d\n", worker_number);
    } else {
      Serial.printf("Worker %d is idle\n", worker_number);
    }
  }
}

void setup() {
  Serial.begin(115200);
  while (!Serial) {
    delay(100);
  }

  // Create the binary semaphore
  package_delivered_semaphore = xSemaphoreCreateBinary();

  if (package_delivered_semaphore == NULL) {
    Serial.println("Failed to create semaphore");
    while (1);
  }

  // Create multiple delivery truck tasks
  for (int i = 0; i < 5; i++) {
    if (xTaskCreate(delivery_truck_task, "Delivery Truck", 2048, (void *)(intptr_t)i, tskIDLE_PRIORITY, NULL) != pdPASS) {
      Serial.printf("Failed to create Delivery Truck %d\n", i);
    } else {
      Serial.printf("Delivery Truck %d created\n", i);
    }
  }

  // Create multiple warehouse worker tasks
  for (int i = 0; i < 1; i++) {
    if (xTaskCreate(warehouse_worker_task, "Warehouse Worker", 2048, (void *)(intptr_t)i, tskIDLE_PRIORITY, NULL) != pdPASS) {
      Serial.printf("Failed to create Warehouse Worker %d\n", i);
    } else {
      Serial.printf("Worker %d created\n", i);
    }
  }
}

void loop() {
  // Nothing to do here
}