-- CL8: instance health monitoring fields + lock helpers

alter table public.plesk_instances
  add column if not exists health_enabled boolean not null default true,
  add column if not exists health_status text not null default 'unknown',
  add column if not exists health_last_checked_at timestamptz,
  add column if not exists health_last_ok_at timestamptz,
  add column if not exists health_last_error text,
  add column if not exists health_last_latency_ms integer,
  add column if not exists health_check_frequency_minutes integer not null default 30,
  add column if not exists health_next_check_at timestamptz,
  add column if not exists health_lock_until timestamptz,
  add column if not exists health_lock_token text;

alter table public.plesk_instances
  drop constraint if exists plesk_instances_health_status_check;

alter table public.plesk_instances
  add constraint plesk_instances_health_status_check
  check (health_status in ('ok', 'degraded', 'down', 'unknown'));

alter table public.plesk_instances
  drop constraint if exists plesk_instances_health_check_frequency_minutes_check;

alter table public.plesk_instances
  add constraint plesk_instances_health_check_frequency_minutes_check
  check (health_check_frequency_minutes between 5 and 10080);

create index if not exists idx_plesk_instances_health_due
  on public.plesk_instances (health_enabled, health_next_check_at);

create or replace function public.acquire_instance_health_lock(
  p_instance_id uuid,
  p_lock_token text,
  p_ttl_seconds integer default 300,
  p_force boolean default false
)
returns boolean
language plpgsql
security definer
set search_path = public
as $$
declare
  v_acquired boolean := false;
begin
  update public.plesk_instances
  set
    health_lock_until = now() + make_interval(secs => p_ttl_seconds),
    health_lock_token = p_lock_token
  where id = p_instance_id
    and health_enabled = true
    and (
      p_force = true
      or health_next_check_at is null
      or health_next_check_at <= now()
    )
    and (health_lock_until is null or health_lock_until < now());

  get diagnostics v_acquired = row_count;
  return v_acquired;
end;
$$;

create or replace function public.release_instance_health_lock(
  p_instance_id uuid,
  p_lock_token text
)
returns void
language sql
security definer
set search_path = public
as $$
  update public.plesk_instances
  set health_lock_until = null,
      health_lock_token = null
  where id = p_instance_id
    and health_lock_token = p_lock_token;
$$;