-- extensions
CREATE EXTENSION IF NOT EXISTS "plv8" SCHEMA pg_catalog;
CREATE EXTENSION IF NOT EXISTS "pg_cron" SCHEMA pg_catalog;
CREATE EXTENSION IF NOT EXISTS "pg_net" SCHEMA extensions;

-- request ID is inserted by first cron job,
-- then second cron job updates from net._http_response table.
create table if not exists raw_bus_positions (
  id BIGINT GENERATED ALWAYS AS IDENTITY,
  request_id INT not null,
  created TIMESTAMP WITH TIME ZONE not null default now(),
  response_status INT null,
  response_json JSONB null
);

-- used to help craft the API URL. Requires plv8 extension.
-- because we are lazy. just use javascript in the database. why not?
create or replace function to_straeto_querystring(jsonb) returns text
language plv8 strict immutable as $$
  const obj = $1;
  return Object.keys(obj).map(function(variableName) {
    const variableValue = obj[variableName];
    if (typeof variableValue == 'object') {
      return encodeURIComponent(variableName) + '=' + encodeURIComponent(JSON.stringify(variableValue));
    } else {
      return encodeURIComponent(variableName) + '=' + encodeURIComponent(variableValue);
    }
  }).join('&');
$$;

create or replace function create_straeto_parameters(bus_routes text[]) returns jsonb
language plpgsql as $$
  declare query_params jsonb;
  begin
    query_params := '{
      "operationName": "BusLocationByRoute",
      "variables": { "trips":[], "routes": [] },
      "extensions": {
        "persistedQuery": {
          "version": 1,
          "sha256Hash": "8f9ee84171961f8a3b9a9d1a7b2a7ac49e7e122e1ba1727e75cfe3a94ff3edb8"
        }
      }
    }'::jsonb;

    select into query_params
		jsonb_set(query_params, '{variables, routes}', array_to_json(bus_routes)::jsonb);
    return query_params;
  end
$$;

create or replace function create_api_url(bus_routes text[]) returns text language sql as $$
  select concat(
    'https://straeto.is/graphql?',
    to_straeto_querystring(create_straeto_parameters(bus_routes))
  );
$$;

create or replace function gather_bus_data()
returns void language sql
as $$
  insert into raw_bus_positions (request_id) select
  net.http_get(
    url := create_api_url(array['1', '2', '3']),
    headers := '{"Content-Type": "application/json"}'::jsonb
  );
$$;
