from functools import partial

from deepdiff import DeepDiff

from agentdojo.default_suites.v1.tools.calendar_client import (
    Calendar,
    cancel_calendar_event,
    create_calendar_event,
    get_day_calendar_events,
    search_calendar_events,
)
from agentdojo.default_suites.v1.tools.email_client import Inbox, send_email
from agentdojo.default_suites.v1.tools.travel_booking_client import (
    CarRental,
    Flights,
    Hotels,
    Reservation,
    Restaurants,
    User,
    check_restaurant_opening_hours,
    get_all_car_rental_companies_in_city,
    get_all_hotels_in_city,
    get_all_restaurants_in_city,
    get_car_fuel_options,
    get_car_price_per_day,
    get_car_rental_address,
    get_car_types_available,
    get_contact_information_for_restaurants,
    get_cuisine_type_for_restaurants,
    get_dietary_restrictions_for_all_restaurants,
    get_flight_information,
    get_hotels_address,
    get_hotels_prices,
    get_price_for_restaurants,
    get_rating_reviews_for_car_rental,
    get_rating_reviews_for_hotels,
    get_rating_reviews_for_restaurants,
    get_restaurants_address,
    get_user_information,
    reserve_car_rental,
    reserve_hotel,
    reserve_restaurant,
)
from agentdojo.functions_runtime import TaskEnvironment, make_function
from agentdojo.task_suite.task_suite import TaskSuite


class TravelEnvironment(TaskEnvironment):
    hotels: Hotels
    restaurants: Restaurants
    car_rental: CarRental
    flights: Flights
    user: User
    calendar: Calendar
    reservation: Reservation
    inbox: Inbox


TOOLS = [
    # User functions
    get_user_information,
    # Hotel functions
    get_all_hotels_in_city,
    get_hotels_prices,
    get_rating_reviews_for_hotels,
    get_hotels_address,
    # Restaurant functions
    get_all_restaurants_in_city,
    get_cuisine_type_for_restaurants,
    get_restaurants_address,
    get_rating_reviews_for_restaurants,  # get_rating_reviews_for_restaurants
    get_dietary_restrictions_for_all_restaurants,
    get_contact_information_for_restaurants,
    get_price_for_restaurants,
    check_restaurant_opening_hours,
    # Car rental functions
    get_all_car_rental_companies_in_city,
    get_car_types_available,
    get_rating_reviews_for_car_rental,
    get_car_fuel_options,
    get_car_rental_address,
    get_car_price_per_day,
    # Calendar functions
    create_calendar_event,
    search_calendar_events,
    get_day_calendar_events,
    cancel_calendar_event,
    # For making a reservation
    reserve_hotel,
    reserve_car_rental,
    reserve_restaurant,
    # For getting flights
    get_flight_information,
    # For sending emails
    send_email,
]

deepdiff_paths_to_exclude = [
    "root.inbox.sent",
    "root.inbox.received",
    "root.inbox.drafts",
    "root.responses",
    "root.model_fields_set",
    "root.calendar.initial_events",
    "root.inbox.initial_emails",
    "root.cloud_drive.initial_files",
]


TravelDeepDiff = partial(DeepDiff, exclude_paths=deepdiff_paths_to_exclude)

task_suite = TaskSuite[TravelEnvironment]("travel", TravelEnvironment, [make_function(tool) for tool in TOOLS])
