//! This code was AUTOGENERATED using the Codama library.
use juniper::{graphql_object, FieldResult};

pub struct QueryRoot;

#[graphql_object(context = crate::graphql::context::GraphQLContext)]
impl QueryRoot {
    // Accounts

    // Instructions (per-instruction list and lookup by signature+index)
    async fn initialize(
        context: &crate::graphql::context::GraphQLContext,
        signature: String,
        instruction_index: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::InitializeGraphQL>> {
        let rows: Vec<crate::instructions::postgres::InitializeRow> = sqlx::query_as(
            r#"SELECT * FROM initialize_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
        )
        .bind(signature)
        .bind(instruction_index)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }

    async fn list_initialize(
        context: &crate::graphql::context::GraphQLContext,
        limit: i32,
        offset: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::InitializeGraphQL>> {
        let rows: Vec<crate::instructions::postgres::InitializeRow> = sqlx::query_as(
            r#"SELECT * FROM initialize_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
        )
        .bind(limit)
        .bind(offset)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }

    async fn swap(
        context: &crate::graphql::context::GraphQLContext,
        signature: String,
        instruction_index: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::SwapGraphQL>> {
        let rows: Vec<crate::instructions::postgres::SwapRow> = sqlx::query_as(
            r#"SELECT * FROM swap_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
        )
        .bind(signature)
        .bind(instruction_index)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }

    async fn list_swap(
        context: &crate::graphql::context::GraphQLContext,
        limit: i32,
        offset: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::SwapGraphQL>> {
        let rows: Vec<crate::instructions::postgres::SwapRow> = sqlx::query_as(
            r#"SELECT * FROM swap_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
        )
        .bind(limit)
        .bind(offset)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }

    async fn deposit_all_token_types(
        context: &crate::graphql::context::GraphQLContext,
        signature: String,
        instruction_index: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::DepositAllTokenTypesGraphQL>> {
        let rows: Vec<crate::instructions::postgres::DepositAllTokenTypesRow> = sqlx::query_as(
            r#"SELECT * FROM deposit_all_token_types_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
        )
        .bind(signature)
        .bind(instruction_index)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }

    async fn list_deposit_all_token_types(
        context: &crate::graphql::context::GraphQLContext,
        limit: i32,
        offset: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::DepositAllTokenTypesGraphQL>> {
        let rows: Vec<crate::instructions::postgres::DepositAllTokenTypesRow> = sqlx::query_as(
            r#"SELECT * FROM deposit_all_token_types_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
        )
        .bind(limit)
        .bind(offset)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }

    async fn withdraw_all_token_types(
        context: &crate::graphql::context::GraphQLContext,
        signature: String,
        instruction_index: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::WithdrawAllTokenTypesGraphQL>> {
        let rows: Vec<crate::instructions::postgres::WithdrawAllTokenTypesRow> = sqlx::query_as(
            r#"SELECT * FROM withdraw_all_token_types_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
        )
        .bind(signature)
        .bind(instruction_index)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }

    async fn list_withdraw_all_token_types(
        context: &crate::graphql::context::GraphQLContext,
        limit: i32,
        offset: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::WithdrawAllTokenTypesGraphQL>> {
        let rows: Vec<crate::instructions::postgres::WithdrawAllTokenTypesRow> = sqlx::query_as(
            r#"SELECT * FROM withdraw_all_token_types_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
        )
        .bind(limit)
        .bind(offset)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }

    async fn deposit_single_token_type_exact_amount_in(
        context: &crate::graphql::context::GraphQLContext,
        signature: String,
        instruction_index: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::DepositSingleTokenTypeExactAmountInGraphQL>>
    {
        let rows: Vec<crate::instructions::postgres::DepositSingleTokenTypeExactAmountInRow> = sqlx::query_as(
            r#"SELECT * FROM deposit_single_token_type_exact_amount_in_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
        )
        .bind(signature)
        .bind(instruction_index)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }

    async fn list_deposit_single_token_type_exact_amount_in(
        context: &crate::graphql::context::GraphQLContext,
        limit: i32,
        offset: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::DepositSingleTokenTypeExactAmountInGraphQL>>
    {
        let rows: Vec<crate::instructions::postgres::DepositSingleTokenTypeExactAmountInRow> = sqlx::query_as(
            r#"SELECT * FROM deposit_single_token_type_exact_amount_in_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
        )
        .bind(limit)
        .bind(offset)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }

    async fn withdraw_single_token_type_exact_amount_out(
        context: &crate::graphql::context::GraphQLContext,
        signature: String,
        instruction_index: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::WithdrawSingleTokenTypeExactAmountOutGraphQL>>
    {
        let rows: Vec<crate::instructions::postgres::WithdrawSingleTokenTypeExactAmountOutRow> = sqlx::query_as(
            r#"SELECT * FROM withdraw_single_token_type_exact_amount_out_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
        )
        .bind(signature)
        .bind(instruction_index)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }

    async fn list_withdraw_single_token_type_exact_amount_out(
        context: &crate::graphql::context::GraphQLContext,
        limit: i32,
        offset: i32,
    ) -> FieldResult<Vec<crate::instructions::graphql::WithdrawSingleTokenTypeExactAmountOutGraphQL>>
    {
        let rows: Vec<crate::instructions::postgres::WithdrawSingleTokenTypeExactAmountOutRow> = sqlx::query_as(
            r#"SELECT * FROM withdraw_single_token_type_exact_amount_out_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
        )
        .bind(limit)
        .bind(offset)
        .fetch_all(&*context.pool)
        .await
        .map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
        Ok(rows
            .into_iter()
            .filter_map(|row| row.try_into().ok())
            .collect())
    }
}
