#pragma once

#include "foundation/result.h"

#include <limits>

namespace pp::app {

struct AppStartupPlan {
    int previous_run_counter = 0;
    int next_run_counter = 1;
    bool save_preferences = true;
    bool start_timelapse = false;
    bool vr_controllers_enabled = true;
    bool show_license_warning = false;
};

class AppStartupServices {
public:
    virtual ~AppStartupServices() = default;

    virtual void store_run_counter(int value) = 0;
    virtual void save_preferences() = 0;
    virtual void start_timelapse_recording() = 0;
    virtual void apply_vr_controllers_enabled(bool enabled) = 0;
    virtual void show_license_warning() = 0;
};

[[nodiscard]] inline pp::foundation::Result<AppStartupPlan> plan_app_startup(
    int current_run_counter,
    bool auto_timelapse_enabled,
    bool stored_vr_controllers_enabled,
    bool license_valid)
{
    if (current_run_counter < 0) {
        return pp::foundation::Result<AppStartupPlan>::failure(
            pp::foundation::Status::invalid_argument("run counter must not be negative"));
    }

    if (current_run_counter == std::numeric_limits<int>::max()) {
        return pp::foundation::Result<AppStartupPlan>::failure(
            pp::foundation::Status::out_of_range("run counter would overflow"));
    }

    AppStartupPlan plan;
    plan.previous_run_counter = current_run_counter;
    plan.next_run_counter = current_run_counter + 1;
    plan.start_timelapse = auto_timelapse_enabled;
    plan.vr_controllers_enabled = stored_vr_controllers_enabled;
    plan.show_license_warning = !license_valid;
    return pp::foundation::Result<AppStartupPlan>::success(plan);
}

[[nodiscard]] inline pp::foundation::Status execute_app_startup_plan(
    const AppStartupPlan& plan,
    AppStartupServices& services)
{
    if (plan.previous_run_counter < 0 || plan.next_run_counter <= plan.previous_run_counter) {
        return pp::foundation::Status::invalid_argument("startup plan has invalid run counter state");
    }

    services.store_run_counter(plan.next_run_counter);
    if (plan.save_preferences) {
        services.save_preferences();
    }
    if (plan.start_timelapse) {
        services.start_timelapse_recording();
    }
    services.apply_vr_controllers_enabled(plan.vr_controllers_enabled);
    if (plan.show_license_warning) {
        services.show_license_warning();
    }

    return pp::foundation::Status::success();
}

[[nodiscard]] inline pp::foundation::Status execute_app_startup_persistence_plan(
    const AppStartupPlan& plan,
    AppStartupServices& services)
{
    if (plan.previous_run_counter < 0 || plan.next_run_counter <= plan.previous_run_counter) {
        return pp::foundation::Status::invalid_argument("startup plan has invalid run counter state");
    }

    services.store_run_counter(plan.next_run_counter);
    if (plan.save_preferences) {
        services.save_preferences();
    }

    return pp::foundation::Status::success();
}

[[nodiscard]] inline pp::foundation::Status execute_app_startup_runtime_plan(
    const AppStartupPlan& plan,
    AppStartupServices& services)
{
    if (plan.previous_run_counter < 0 || plan.next_run_counter <= plan.previous_run_counter) {
        return pp::foundation::Status::invalid_argument("startup plan has invalid run counter state");
    }

    if (plan.start_timelapse) {
        services.start_timelapse_recording();
    }
    services.apply_vr_controllers_enabled(plan.vr_controllers_enabled);
    if (plan.show_license_warning) {
        services.show_license_warning();
    }

    return pp::foundation::Status::success();
}

} // namespace pp::app
