import { InboundPolicyHandler } from "@zuplo/runtime";
import { OutboundPolicyHandler } from "@zuplo/runtime";

/**
 * Policy that limits the complexity and depth of GraphQL queries to prevent abuse.
 * Protects your GraphQL API from expensive queries that could cause performance issues
 * or denial of service attacks.
 *
 * @title GraphQL Complexity Limit
 * @product api-gateway
 * @public
 *
 * @param request - The incoming ZuploRequest containing the GraphQL query
 * @param context - The ZuploContext
 * @param options - Configuration for complexity and depth limits
 * @param policyName - The name of the policy instance
 * @returns The request if within limits, or a 400 response if limits exceeded
 *
 * @example
 * ```json
 * // policies.json - Limit query complexity
 * {
 *   "name": "graphql-complexity",
 *   "policyType": "graphql-complexity-limit-inbound",
 *   "handler": {
 *     "export": "GraphQLComplexityLimitInboundPolicy",
 *     "module": "$import(@zuplo/graphql)",
 *     "options": {
 *       "useComplexityLimit": {
 *         "complexityLimit": 1000,
 *         "endpointUrl": "https://api.example.com/graphql"
 *       }
 *     }
 *   }
 * }
 * ```
 *
 * @example
 * ```json
 * // Limit query depth to prevent deeply nested queries
 * {
 *   "handler": {
 *     "export": "GraphQLComplexityLimitInboundPolicy",
 *     "module": "$import(@zuplo/graphql)",
 *     "options": {
 *       "useDepthLimit": {
 *         "depthLimit": 10
 *       }
 *     }
 *   }
 * }
 * ```
 *
 * @example
 * ```json
 * // Use both complexity and depth limits
 * {
 *   "handler": {
 *     "export": "GraphQLComplexityLimitInboundPolicy",
 *     "module": "$import(@zuplo/graphql)",
 *     "options": {
 *       "useComplexityLimit": {
 *         "complexityLimit": 500,
 *         "endpointUrl": "$env(GRAPHQL_ENDPOINT)"
 *       },
 *       "useDepthLimit": {
 *         "depthLimit": 7
 *       }
 *     }
 *   }
 * }
 * ```
 */
export declare const GraphQLComplexityLimitInboundPolicy: InboundPolicyHandler<GraphQLComplexityLimitInboundPolicyOptions>;

/**
 * The options for this policy.
 * @public
 */
export declare interface GraphQLComplexityLimitInboundPolicyOptions {
  useComplexityLimit: {
    /**
     * The maximum complexity a query is allowed to have.
     */
    complexityLimit?: number;
    /**
     * The endpoint URL to use for the complexity calculation.
     */
    endpointUrl?: string;
  };
  useDepthLimit: {
    /**
     * The maximum depth a query is allowed to have.
     */
    depthLimit?: number;
    /**
     * The fields to ignore when calculating the depth of a query.
     */
    ignore?: string[];
  };
}

/**
 * Policy that disables GraphQL introspection queries in production.
 * Introspection allows clients to discover the schema, which can be a security
 * risk as it exposes your entire API structure.
 *
 * @title GraphQL Disable Introspection
 * @product api-gateway
 * @public
 *
 * @param request - The incoming ZuploRequest containing the GraphQL query
 * @param context - The ZuploContext
 * @param options - Policy configuration options
 * @param policyName - The name of the policy instance
 * @returns The request if not an introspection query, or a 403 response if introspection is attempted
 *
 * @example
 * ```json
 * // policies.json - Disable introspection in production
 * {
 *   "name": "disable-introspection",
 *   "policyType": "graphql-disable-introspection-inbound",
 *   "handler": {
 *     "export": "GraphQLDisableIntrospectionInboundPolicy",
 *     "module": "$import(@zuplo/graphql)"
 *   }
 * }
 * ```
 *
 * @example
 * ```json
 * // Apply to specific routes
 * {
 *   "paths": {
 *     "/graphql": {
 *       "post": {
 *         "x-zuplo-route": {
 *           "policies": {
 *             "inbound": ["disable-introspection", "rate-limit"]
 *           },
 *           "handler": {
 *             "export": "graphqlHandler",
 *             "module": "$import(./handlers/graphql)"
 *           }
 *         }
 *       }
 *     }
 *   }
 * }
 * ```
 *
 * @remarks
 * This policy blocks queries containing __schema or __type fields,
 * which are used by GraphQL introspection. It's recommended to disable
 * introspection in production environments while keeping it enabled
 * in development for tooling support.
 */
export declare const GraphQLDisableIntrospectionInboundPolicy: InboundPolicyHandler<GraphqlDisableIntrospectionInboundPolicyOptions>;

/**
 * The options for this policy.
 * @public
 */
export declare interface GraphqlDisableIntrospectionInboundPolicyOptions {}

/**
 * Filters GraphQL introspection responses to exclude specific types and fields.
 *
 * This policy intercepts GraphQL introspection query responses and removes
 * configured types and fields from the schema. Useful for hiding internal
 * types or sensitive fields from the public schema.
 *
 * @title GraphQL Introspection Filter
 * @product api-gateway
 * @public
 * @param response - The Response from the upstream
 * @param request - The ZuploRequest
 * @param context - The ZuploContext
 * @param options - The policy options set in policies.json
 * @param policyName - The name of the policy as set in policies.json
 * @returns A Response with filtered introspection data
 * @example
 * ```json
 * {
 *   "name": "graphql-introspection-filter",
 *   "policyType": "graphql-introspection-filter-outbound",
 *   "handler": {
 *     "export": "GraphQLIntrospectionFilterOutboundPolicy",
 *     "module": "$import(@zuplo/runtime)",
 *     "options": {
 *       "excludeTypes": ["UserInternal", "AdminType"],
 *       "excludeTypeFields": {
 *         "User": ["password", "ssn"],
 *         "Query": ["adminUsers", "debugInfo"]
 *       }
 *     }
 *   }
 * }
 * ```
 */
export declare const GraphQLIntrospectionFilterOutboundPolicy: OutboundPolicyHandler<GraphQLIntrospectionFilterOutboundPolicyOptions>;

/**
 * The options for the GraphQL introspection filtering outbound policy.
 * @public
 */
export declare interface GraphQLIntrospectionFilterOutboundPolicyOptions {
  /**
   * GraphQL Types to exclude from the schema (exact match).
   */
  excludeTypes?: string[];
  /**
   * Fields on specific GraphQL Types to exclude.
   */
  excludeTypeFields?: {
    [k: string]: string[];
  };
}

export {};
