# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

sources:
    postgresql-source:
        kind: postgres
        host: ${POSTGRES_HOST:localhost}
        port: ${POSTGRES_PORT:5432}
        database: ${POSTGRES_DATABASE}
        user: ${POSTGRES_USER}
        password: ${POSTGRES_PASSWORD}
        queryParams: ${POSTGRES_QUERY_PARAMS:}

tools:
    execute_sql:
        kind: postgres-execute-sql
        source: postgresql-source
        description: Use this tool to execute SQL.

    list_tables:
        kind: postgres-list-tables
        source: postgresql-source
        description: "Lists detailed schema information (object type, columns, constraints, indexes, triggers, owner, comment) as JSON for user-created tables (ordinary or partitioned). Filters by a comma-separated list of names. If names are omitted, lists all tables in user schemas."

    list_active_queries:
        kind: postgres-list-active-queries
        source: postgresql-source
        description: "List the top N (default 50) currently running queries (state='active') from pg_stat_activity, ordered by longest-running first. Returns pid, user, database, application_name, client_addr, state, wait_event_type/wait_event, backend/xact/query start times, computed query_duration, and the SQL text."

    list_available_extensions:
        kind: postgres-list-available-extensions
        source: postgresql-source
        description: "Discover all PostgreSQL extensions available for installation on this server, returning name, default_version, and description."

    list_installed_extensions:
        kind: postgres-list-installed-extensions
        source: postgresql-source
        description: "List all installed PostgreSQL extensions with their name, version, schema, owner, and description."

    long_running_transactions:
        kind: postgres-long-running-transactions
        source: postgresql-source
        description: "Identifies and lists database transactions that exceed a specified time limit. For each of the long running transactions, the output contains the process id, database name, user name, application name, client address, state, connection age, transaction age, query age, last activity age, wait event type, wait event, and query string."

    list_locks:
        kind: postgres-list-locks
        source: postgresql-source
        description: "Identifies all locks held by active processes showing the process ID, user, query text, and an aggregated list of all transactions and specific locks (relation, mode, grant status) associated with each process."

    replication_stats:
        kind: postgres-replication-stats
        source: postgresql-source
        description: "Lists each replica's process ID, user name, application name, backend_xmin (standby's xmin horizon reported by hot_standby_feedback), client IP address, connection state, and sync_state, along with lag sizes in bytes for sent_lag (primary to sent), write_lag (sent to written), flush_lag (written to flushed), replay_lag (flushed to replayed), and the overall total_lag (primary to replayed)."

    list_autovacuum_configurations:
        kind: postgres-sql
        source: postgresql-source
        description: "List PostgreSQL autovacuum-related configurations (name and current setting) from pg_settings."
        statement: |
            SELECT name,
                setting
            FROM   pg_settings
            WHERE  category = 'Autovacuum';

    list_memory_configurations:
        kind: postgres-sql
        source: postgresql-source
        description: "List PostgreSQL memory-related configurations (name and current setting) from pg_settings."
        statement: |
            (
                SELECT
                name,
                pg_size_pretty((setting::bigint * 1024)::bigint) setting
                FROM pg_settings
                WHERE name IN ('work_mem', 'maintenance_work_mem')
            )
            UNION ALL
            (
                SELECT
                name,
                pg_size_pretty((((setting::bigint) * 8) * 1024)::bigint)
                FROM pg_settings
                WHERE name IN ('shared_buffers', 'wal_buffers', 'effective_cache_size', 'temp_buffers')
            )
            ORDER BY 1 DESC;

    list_top_bloated_tables:
        kind: postgres-sql
        source: postgresql-source
        description: |
            List the top tables by dead-tuple (approximate bloat signal), returning schema, table, live/dead tuples, percentage, and last vacuum/analyze times.
        statement: |
            SELECT
                schemaname AS schema_name,
                relname AS relation_name,
                n_live_tup AS live_tuples,
                n_dead_tup AS dead_tuples,
                TRUNC((n_dead_tup::NUMERIC / NULLIF(n_live_tup + n_dead_tup, 0)) * 100, 2) AS dead_tuple_percentage,
                last_vacuum,
                last_autovacuum,
                last_analyze,
                last_autoanalyze
            FROM pg_stat_user_tables
            ORDER BY n_dead_tup DESC
            LIMIT COALESCE($1::int, 50);
        parameters:
            - name: limit
              description: "The maximum number of results to return."
              type: integer
              default: 50

    list_replication_slots:
        kind: postgres-sql
        source: postgresql-source
        description: "List key details for all PostgreSQL replication slots (e.g., type, database, active status) and calculates the size of the outstanding WAL that is being prevented from removal by the slot."
        statement: |
            SELECT
            slot_name,
            slot_type,
            plugin,
            database,
            temporary,
            active,
            restart_lsn,
            confirmed_flush_lsn,
            xmin,
            catalog_xmin,
            pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal
            FROM pg_replication_slots;

    list_invalid_indexes:
        kind: postgres-sql
        source: postgresql-source
        description: "Lists all invalid PostgreSQL indexes which are taking up disk space but are unusable by the query planner. Typically created by failed CREATE INDEX CONCURRENTLY operations."
        statement: |
            SELECT
                nspname AS schema_name,
                indexrelid::regclass AS index_name,
                indrelid::regclass AS table_name,
                pg_size_pretty(pg_total_relation_size(indexrelid)) AS index_size,
                indisready,
                indisvalid,
                pg_get_indexdef(pg_class.oid) AS index_def
            FROM pg_index
            JOIN pg_class ON pg_class.oid = pg_index.indexrelid
            JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
            WHERE indisvalid = FALSE;

    get_query_plan:
        kind: postgres-sql
        source: postgresql-source
        description: "Generate a PostgreSQL EXPLAIN plan in JSON format for a single SQL statement—without executing it. This returns the optimizer's estimated plan, costs, and rows (no ANALYZE, no extra options). Use in production safely for plan inspection, regression checks, and query tuning workflows."
        statement: |
            EXPLAIN (FORMAT JSON) {{.query}};
        templateParameters:
            - name: query
              type: string
              description: "The SQL statement for which you want to generate plan (omit the EXPLAIN keyword)."
              required: true

    list_views:
        kind: postgres-list-views
        source: postgresql-source

    list_schemas:
        kind: postgres-list-schemas
        source: postgresql-source
    
    database_overview:
        kind: postgres-database-overview
        source: postgresql-source

    list_triggers:
        kind: postgres-list-triggers
        source: postgresql-source 

    list_indexes:
        kind: postgres-list-indexes
        source: postgresql-source

    list_sequences:
        kind: postgres-list-sequences
        source: postgresql-source

    list_query_stats:
        kind: postgres-list-query-stats
        source: postgresql-source

    get_column_cardinality:
        kind: postgres-get-column-cardinality
        source: postgresql-source

    list_table_stats:
        kind: postgres-list-table-stats
        source: postgresql-source

    list_publication_tables:
        kind: postgres-list-publication-tables
        source: postgresql-source

    list_tablespaces:
        kind: postgres-list-tablespaces
        source: postgresql-source

    list_pg_settings:
        kind: postgres-list-pg-settings
        source: postgresql-source
    
    list_database_stats:
        kind: postgres-list-database-stats
        source: postgresql-source

    list_roles:
        kind: postgres-list-roles
        source: postgresql-source

    list_stored_procedure:
        kind: postgres-list-stored-procedure
        source: postgresql-source

toolsets:
    postgres_database_tools:
        - execute_sql
        - list_tables
        - list_active_queries
        - list_available_extensions
        - list_installed_extensions
        - list_autovacuum_configurations
        - list_memory_configurations
        - list_top_bloated_tables
        - list_replication_slots
        - list_invalid_indexes
        - get_query_plan
        - list_views
        - list_schemas
        - database_overview
        - list_triggers
        - list_indexes
        - list_sequences
        - long_running_transactions
        - list_locks
        - replication_stats
        - list_query_stats
        - get_column_cardinality
        - list_publication_tables
        - list_tablespaces
        - list_pg_settings
        - list_database_stats
        - list_roles
        - list_table_stats
        - list_stored_procedure
