CREATE TABLE task_types (
    id bigserial PRIMARY KEY,
    name varchar(128) NOT NULL UNIQUE,
    time_limit integer NOT NULL,
    schedule varchar(64) NOT NULL,
    restorable boolean DEFAULT FALSE NOT NULL
);


CREATE TABLE tasks (
    id bigserial PRIMARY KEY,
    type_id bigint NOT NULL REFERENCES task_types (id),
    created timestamptz NOT NULL DEFAULT now(),
    intake_time timestamptz NOT NULL DEFAULT now(),
    status varchar(128) NOT NULL,
    scheduled_time timestamptz NOT NULL,
    current_log_id bigint
);

CREATE INDEX tasks_status_in_progress_btree_index ON tasks
    USING btree (status)
    WHERE (status not in ('completed', 'failed'));

CREATE INDEX tasks_type_id_btree_index ON tasks
    USING btree (created);

CREATE INDEX tasks_intake_time_btree_index ON tasks
    USING btree (intake_time);

CREATE INDEX tasks_scheduled_time_btree_index ON tasks
    USING btree (scheduled_time);

CREATE INDEX tasks_type_id_created_status_failed_btree_index ON tasks
    USING btree (type_id, created DESC)
    WHERE (status = 'failed');


CREATE TABLE tasks_log (
    id bigserial PRIMARY KEY,
    task_id bigint NOT NULL REFERENCES tasks (id),
    created timestamptz NOT NULL DEFAULT now(),
    status varchar(128) NOT NULL,
    executor_id varchar(128),
    metadata jsonb,
    CONSTRAINT uq_tasks_log_executor_id UNIQUE (executor_id, status),
    CONSTRAINT nullable_executor_only_for_failed_status CHECK (
        (executor_id IS NULL and status = 'failed') or executor_id IS NOT NULL
    )
);

CREATE INDEX tasks_log_task_id_btree_index ON tasks_log
    USING btree (task_id);

CREATE INDEX tasks_log_created_btree_index ON tasks_log
    USING btree (created);

CREATE INDEX tasks_log_executor_id_btree_index ON tasks_log
    USING btree (executor_id);

ALTER TABLE tasks
ADD CONSTRAINT fk_tasks_current_log_id_tasks_log
FOREIGN KEY (current_log_id)
REFERENCES tasks_log (id);

INSERT INTO task_types (name, time_limit, schedule, restorable)
VALUES ('adv_store__backup_campaigns_change_log', 600, '0 21 * * *', true),
    ('adv_store__process_direct_moderation_responses', 60, '*/5 * * * *', true),
    ('adv_store__process_direct_moderations', 60, '*/5 * * * *', true),
    ('adv_store__refresh_auto_daily_budgets', 600, '0 * * * *', true),
    ('beekeeper__events_normalizer', 60, '*/5 * * * *', false),
    ('beekeeper__events_normalizer_mapkit', 60, '* * * * *', false),
    ('beekeeper__events_processor', 600, '* * * * *', true),
    ('billing__generate_geoprod_reconciliation_report', 600, '0 4 * * *', true),
    ('billing_sync_client_data', 1800, '0 * * * *', true),
    ('booking_yang__create_missed_clients', 600, '*/5 * * * *', true),
    ('booking_yang__export_created_orders', 600, '*/5 * * * *', true),
    ('booking_yang__export_orders_notified_to_user', 600, '*/5 * * * *', true),
    ('booking_yang__export_orders_processed_by_yang', 600, '*/5 * * * *', true),
    ('booking_yang__import_processed_tasks', 300, '* * * * *', true),
    ('booking_yang__notify_about_processed_tasks', 300, '* * * * *', true),
    ('booking_yang__process_tasks', 300, '* * * * *', true),
    ('booking_yang__send_missed_result_events', 600, '*/5 * * * *', true),
    ('booking_yang__upload_orders', 600, '*/15 * * * *', true),
    ('dealer__notify_about_status_change', 120, '* * * * *', true),
    ('dealer__update_orders_statuses', 120, '* * * * *', true),
    ('drugstore__asna_sync_nomenclature', 1800, '0 2 * * *', true),
    ('drugstore__asna_sync_stocks', 1200, '*/20 * * * *', false),
    ('drugstore__drugs_info_import', 1800, '0 2 * * *', true),
    ('drugstore__geosearch_export', 600, '*/15 * * * *', false),
    ('drugstore__refresh_materialized_views', 60, '0 22 * * *', true),
    ('drugstore__sync_permalinks_of_pharmacies', 1800, '0 12 * * *', true),
    ('drugstore__yandex_health_export', 600, '51 * * * *', true),
    ('export_campaigns', 1800, '* * * * *', false),
    ('feed_maker__import_asna_pharmacies', 600, '0 1 * * *', true),
    ('feed_maker__make_main_feed', 1800, '0 14 * * *', true),
    ('geosmb_cleaner__delete_clients', 600, '* * * * *', true),
    ('geosmb_crane_operator__export_business_coupons_to_yt', 1800, '45 * * * *', true),
    ('geosmb_crane_operator__export_coupons_to_review', 600, '*/5 * * * *', true),
    ('geosmb_crane_operator__export_loyalty_items_to_yt', 1200, '*/15 * * * *', true),
    ('geosmb_crane_operator__export_orgs_with_booking_to_yt', 600, '25 * * * *', true),
    ('geosmb_crane_operator__export_orgs_with_coupons_to_yt', 600, '25 * * * *', true),
    ('geosmb_crane_operator__export_reviewed_to_loyalty', 600, '*/5 * * * *', true),
    ('geosmb_crane_operator__generate_data_for_snippet', 600, '35 * * * *', true),
    ('geosmb_doorman__call_events_import', 3600, '*/10 * * * *', true),
    ('geosmb_doorman__clients_yt_export', 600, '0 23 * * *', true),
    ('geosmb_landlord__import_call_tracking_from_yt', 1200, '*/5 * * * *', true),
    ('geosmb_landlord__import_promo_from_yt', 600, '*/5 * * * *', true),
    ('geosmb_landlord__import_promoted_cta_from_yt', 600, '*/5 * * * *', true),
    ('geosmb_landlord__import_promoted_service_lists_from_yt', 600, '*/5 * * * *', true),
    ('geosmb_landlord__import_promoted_services_from_yt', 600, '*/5 * * * *', true),
    ('geosmb_promoter__export_leads', 21600, '0 23 * * *', true),
    ('geosmb_promoter__import_recent_events', 25200, '0 13 * * *', true),
    ('geosmb_scenarist__export_subscriptions', 600, '5 9 * * *', true),
    ('geosmb_scenarist__export_subscriptions_versions', 600, '*/10 * * * *', true),
    ('geosmb_scenarist__import_certificate_mailing_stats', 600, '0 13 * * *', true),
    ('geosmb_scenarist__import_messages', 1800, '0 * * * *', true),
    ('geosmb_scenarist__process_unsent_emails', 540, '*/10 * * * *', true),
    ('loyalty_int__check_available_special_codes', 120, '0 14 * * *', false),
    ('loyalty_int__redistribution_special_coupon_codes', 180, '*/30 * * * *', false),
    ('loyalty_int__send_coupon_receipt', 120, '*/2 * * * *', false),
    ('loyalty_int__update_business_rubrics', 7200, '0 0 * * *', false),
    ('market_int__send_order_reminders', 90, '*/2 * * * *', true),
    ('payments_int__fetch_payment_access_status', 1800, '0 */1 * * *', false),
    ('points__sync_forecasts', 600, '20 * * * *', false),
    ('refresh_display_probability_for_campaigns', 3600, '10 * * * *', false),
    ('stat_tasks_starter__report_campaigns_not_spending_budget', 60, '30 0 * * *', false),
    ('stop_campaigns_date_end', 15, '0 * * * *', false),
    ('sync_category_search_reports', 3600, '40 * * * *', false),
    ('unstop_campaigns_daily_budget', 15, '1 * * * *', false),
    ('unstop_campaigns_order_balance', 15, '*/30 * * * *', false),
    ('warden__auto_mark_expired_tasks', 60, '* * * * *', true);