# """
# Copyright (c) 2016- 2025, Wiliot Ltd. All rights reserved.
#
# Redistribution and use of the Software in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
#   1. Redistributions of source code must retain the above copyright notice,
#   this list of conditions and the following disclaimer.
#
#   2. Redistributions in binary form, except as used in conjunction with
#   Wiliot's Pixel in a product or a Software update for such product, must reproduce
#   the above copyright notice, this list of conditions and the following disclaimer in
#   the documentation and/or other materials provided with the distribution.
#
#   3. Neither the name nor logo of Wiliot, nor the names of the Software's contributors,
#   may be used to endorse or promote products or services derived from this Software,
#   without specific prior written permission.
#
#   4. This Software, with or without modification, must only be used in conjunction
#   with Wiliot's Pixel or with Wiliot's cloud service.
#
#   5. If any Software is provided in binary form under this license, you must not
#   do any of the following:
#   (a) modify, adapt, translate, or create a derivative work of the Software; or
#   (b) reverse engineer, decompile, disassemble, decrypt, or otherwise attempt to
#   discover the source code or non-literal aspects (such as the underlying structure,
#   sequence, organization, ideas, or algorithms) of the Software.
#
#   6. If you create a derivative work and/or improvement of any Software, you hereby
#   irrevocably grant each of Wiliot and its corporate affiliates a worldwide, non-exclusive,
#   royalty-free, fully paid-up, perpetual, irrevocable, assignable, sublicensable
#   right and license to reproduce, use, make, have made, import, distribute, sell,
#   offer for sale, create derivative works of, modify, translate, publicly perform
#   and display, and otherwise commercially exploit such derivative works and improvements
#   (as applicable) in conjunction with Wiliot's products and services.
#
#   7. You represent and warrant that you are not a resident of (and will not use the
#   Software in) a country that the U.S. government has embargoed for use of the Software,
#   nor are you named on the U.S. Treasury Department's list of Specially Designated
#   Nationals or any other applicable trade sanctioning regulations of any jurisdiction.
#   You must not transfer, export, re-export, import, re-import or divert the Software
#   in violation of any export or re-export control laws and regulations (such as the
#   United States' ITAR, EAR, and OFAC regulations), as well as any applicable import
#   and use restrictions, all as then in effect
#
# THIS SOFTWARE IS PROVIDED BY WILIOT "AS IS" AND "AS AVAILABLE", AND ANY EXPRESS
# OR IMPLIED WARRANTIES OR CONDITIONS, INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED
# WARRANTIES OR CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, NONINFRINGEMENT,
# QUIET POSSESSION, FITNESS FOR A PARTICULAR PURPOSE, AND TITLE, ARE DISCLAIMED.
# IN NO EVENT SHALL WILIOT, ANY OF ITS CORPORATE AFFILIATES OR LICENSORS, AND/OR
# ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES, FOR THE COST OF PROCURING SUBSTITUTE GOODS OR SERVICES,
# FOR ANY LOSS OF USE OR DATA OR BUSINESS INTERRUPTION, AND/OR FOR ANY ECONOMIC LOSS
# (SUCH AS LOST PROFITS, REVENUE, ANTICIPATED SAVINGS). THE FOREGOING SHALL APPLY:
# (A) HOWEVER CAUSED AND REGARDLESS OF THE THEORY OR BASIS LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE);
# (B) EVEN IF ANYONE IS ADVISED OF THE POSSIBILITY OF ANY DAMAGES, LOSSES, OR COSTS; AND
# (C) EVEN IF ANY REMEDY FAILS OF ITS ESSENTIAL PURPOSE.
# """
"""
 The following code snippet shows how to use pyWiliot for Configurable Sensing Events API:
 Please change the owner IDs and other IDs to match your credentials before running this code
"""

# Import the library
from wiliot_api.events.configurable_sensing_events import *
import os

# Define an owner ID
owner_id = "test_owner"  # ToDo: add here your owner ID

# Initialise a Configurable Sensing Events client object
events_client = ConfigurableSensingEventsClient(
    api_key=os.environ.get("WILIOT_API_KEY"),
    owner_id=owner_id
)

# Get a list of all configured events
print(events_client.get_events())

# Get details on a single event by its ID
print(events_client.get_event(event_id="my-event-id"))

# Create a Location Event with on_change trigger
# processor_id defaults to LOCATION_ISOLATED_ZONES (for zones with no signal bleed)
# confidence_threshold defaults to ALL
location_event = events_client.create_location_event(
    event_name="locationChangeEvent",
    asset_category_ids=["my-category-id"],
    event_trigger=EventTrigger.ON_CHANGE,
    description="Triggers when asset location changes",
    confidence_threshold=ConfidenceThreshold.PERCENTAGE_75,
    event_retention_period=60,  # 60 minutes
    zone_labels=[{"id": "zone-label-id", "value": "warehouse-zone"}]
)
print(location_event)

# Create a Location Event with periodic trigger and OverlappingZones processor
# Use LOCATION_OVERLAPPING_ZONES for zones with signal bleed between them
periodic_location_event = events_client.create_location_event(
    event_name="periodicLocationEvent",
    asset_category_ids=["my-category-id"],
    event_trigger=EventTrigger.PERIODIC,
    event_trigger_cadence=15,  # Every 15 minutes
    processor_id=ProcessorId.LOCATION_OVERLAPPING_ZONES,
    processor_template_id=ProcessorTemplateId.NO_ZONE_BLEED,
    include_temperature=True  # Include temperature data (OverlappingZones only)
)
print(periodic_location_event)

# Create a Location Event with on_inactivity trigger
inactivity_event = events_client.create_location_event(
    event_name="inactivityEvent",
    asset_category_ids=["my-category-id"],
    event_trigger=EventTrigger.ON_INACTIVITY,
    event_trigger_visibility_timeout=30  # 30 minutes without data = not visible
)
print(inactivity_event)

# Create a Geolocation Event with on_change trigger
# processor_id defaults to GEOLOCATION
geolocation_event = events_client.create_geolocation_event(
    event_name="geolocationChangeEvent",
    asset_category_ids=["my-category-id"],
    event_trigger=EventTrigger.ON_CHANGE,
    geolocation_distance_threshold=100,  # 100 meters
    description="Triggers when asset moves more than 100 meters"
)
print(geolocation_event)

# Create a Geolocation Event with periodic trigger
periodic_geolocation = events_client.create_geolocation_event(
    event_name="periodicGeolocation",
    asset_category_ids=["my-category-id"],
    event_trigger=EventTrigger.PERIODIC,
    event_trigger_cadence=10  # Every 10 minutes
)
print(periodic_geolocation)

# Create a Temperature Event with periodic trigger
# processor_id defaults to TEMPERATURE
temperature_event = events_client.create_temperature_event(
    event_name="temperatureMonitor",
    asset_category_ids=["my-category-id"],
    event_trigger=EventTrigger.PERIODIC,
    event_trigger_cadence=5,  # Every 5 minutes
    description="Monitor temperature every 5 minutes"
)
print(temperature_event)

# Create a Geofencing Event for on_entry trigger
# processor_id defaults to GEOFENCING
geofence_entry_event = events_client.create_geofencing_event(
    event_name="geofenceEntryEvent",
    asset_category_ids=["my-category-id"],
    event_trigger=EventTrigger.ON_ENTRY,
    geofence_range=500,  # 500 meters radius
    location_labels=[{"id": "location-label-id", "value": "warehouse"}],
    description="Triggers when asset enters the geofence"
)
print(geofence_entry_event)

# Create a Geofencing Event for on_exit trigger
geofence_exit_event = events_client.create_geofencing_event(
    event_name="geofenceExitEvent",
    asset_category_ids=["my-category-id"],
    event_trigger=EventTrigger.ON_EXIT,
    geofence_range=500,  # 500 meters radius
    location_labels=[{"id": "location-label-id", "value": "warehouse"}],
    description="Triggers when asset exits the geofence"
)
print(geofence_exit_event)

# Using the generic create_event method with EventType enum
# When using create_event directly, you must provide processor_id and confidence_threshold
# for Location events (the convenience methods default these for you)
generic_event = events_client.create_event(
    event_name="genericLocationEvent",
    event_type=EventType.LOCATION,
    asset_category_ids=["my-category-id"],
    event_trigger=EventTrigger.PERIODIC,
    event_trigger_cadence=30,
    is_active=True,
    processor_id=ProcessorId.LOCATION_ISOLATED_ZONES,
    confidence_threshold=ConfidenceThreshold.ALL
)
print(generic_event)

# Activate/Deactivate an event
events_client.activate_event(event_id="my-event-id", is_active=True)
events_client.deactivate_event(event_id="my-event-id")

# Update an existing event
# Tip: fetch the original event first to preserve fields you don't want to change
original = events_client.get_event(event_id="my-event-id")
updated_event = events_client.update_event(
    event_id="my-event-id",
    event_name="updatedEventName",
    event_type=original['eventType'],
    asset_category_ids=original['assetCategoryIds'],
    is_active=True,
    event_trigger=EventTrigger.PERIODIC,
    event_trigger_cadence=20,
    processor_id=original.get('processorId'),
    confidence_threshold=original.get('confidenceThreshold'),
    c2c_connection_ids=original.get('c2cConnectionIds', [])
)
print(updated_event)

# Duplicate an event
duplicated_event = events_client.duplicate_event(event_id="my-event-id")
print(duplicated_event)

# Get event metrics (Prometheus metrics)
metrics = events_client.get_event_metrics(
    event_config_id="my-event-config-id",
    duration=3600,  # Last hour (in seconds)
    step=10  # 10 second intervals
)
print(metrics)

# Get processor template configuration
processor_config = events_client.get_processor_template(
    template_id=ProcessorTemplateId.NO_ZONE_BLEED
)
print(processor_config)

# Delete an event (caution: cannot be reversed)
events_client.delete_event(event_id="my-event-id")
