// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
//   protoc-gen-ts_proto  v2.11.8
//   protoc               v3.19.1
// source: rag.proto

/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import {
  type CallOptions,
  type ChannelCredentials,
  Client,
  type ClientOptions,
  type ClientUnaryCall,
  type handleUnaryCall,
  makeGenericClientConstructor,
  type Metadata,
  type ServiceError,
  type UntypedServiceImplementation,
} from "@grpc/grpc-js";
import Long from "long";
import { Principal } from "./common";
import { Struct } from "./google/protobuf/struct";

export interface RagSearchFilters {
  source: string;
  documentId: string;
}

export interface RagSearchRequest {
  query: string;
  topK: number;
  filters?: RagSearchFilters | undefined;
  principal?: Principal | undefined;
}

export interface Chunk {
  id: string;
  documentId: string;
  content: string;
  source: string;
  score: number;
  metadata?: { [key: string]: any } | undefined;
}

export interface RagSearchResponse {
  chunks: Chunk[];
  correlationId: string;
}

function createBaseRagSearchFilters(): RagSearchFilters {
  return { source: "", documentId: "" };
}

export const RagSearchFilters: MessageFns<RagSearchFilters> = {
  encode(message: RagSearchFilters, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.source !== "") {
      writer.uint32(10).string(message.source);
    }
    if (message.documentId !== "") {
      writer.uint32(18).string(message.documentId);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): RagSearchFilters {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    const end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseRagSearchFilters();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.source = reader.string();
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.documentId = reader.string();
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): RagSearchFilters {
    return {
      source: isSet(object.source) ? globalThis.String(object.source) : "",
      documentId: isSet(object.documentId)
        ? globalThis.String(object.documentId)
        : isSet(object.document_id)
        ? globalThis.String(object.document_id)
        : "",
    };
  },

  toJSON(message: RagSearchFilters): unknown {
    const obj: any = {};
    if (message.source !== "") {
      obj.source = message.source;
    }
    if (message.documentId !== "") {
      obj.documentId = message.documentId;
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<RagSearchFilters>, I>>(base?: I): RagSearchFilters {
    return RagSearchFilters.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<RagSearchFilters>, I>>(object: I): RagSearchFilters {
    const message = createBaseRagSearchFilters();
    message.source = object.source ?? "";
    message.documentId = object.documentId ?? "";
    return message;
  },
};

function createBaseRagSearchRequest(): RagSearchRequest {
  return { query: "", topK: 0, filters: undefined, principal: undefined };
}

export const RagSearchRequest: MessageFns<RagSearchRequest> = {
  encode(message: RagSearchRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.query !== "") {
      writer.uint32(10).string(message.query);
    }
    if (message.topK !== 0) {
      writer.uint32(16).int32(message.topK);
    }
    if (message.filters !== undefined) {
      RagSearchFilters.encode(message.filters, writer.uint32(26).fork()).join();
    }
    if (message.principal !== undefined) {
      Principal.encode(message.principal, writer.uint32(34).fork()).join();
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): RagSearchRequest {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    const end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseRagSearchRequest();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.query = reader.string();
          continue;
        }
        case 2: {
          if (tag !== 16) {
            break;
          }

          message.topK = reader.int32();
          continue;
        }
        case 3: {
          if (tag !== 26) {
            break;
          }

          message.filters = RagSearchFilters.decode(reader, reader.uint32());
          continue;
        }
        case 4: {
          if (tag !== 34) {
            break;
          }

          message.principal = Principal.decode(reader, reader.uint32());
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): RagSearchRequest {
    return {
      query: isSet(object.query) ? globalThis.String(object.query) : "",
      topK: isSet(object.topK)
        ? globalThis.Number(object.topK)
        : isSet(object.top_k)
        ? globalThis.Number(object.top_k)
        : 0,
      filters: isSet(object.filters) ? RagSearchFilters.fromJSON(object.filters) : undefined,
      principal: isSet(object.principal) ? Principal.fromJSON(object.principal) : undefined,
    };
  },

  toJSON(message: RagSearchRequest): unknown {
    const obj: any = {};
    if (message.query !== "") {
      obj.query = message.query;
    }
    if (message.topK !== 0) {
      obj.topK = Math.round(message.topK);
    }
    if (message.filters !== undefined) {
      obj.filters = RagSearchFilters.toJSON(message.filters);
    }
    if (message.principal !== undefined) {
      obj.principal = Principal.toJSON(message.principal);
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<RagSearchRequest>, I>>(base?: I): RagSearchRequest {
    return RagSearchRequest.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<RagSearchRequest>, I>>(object: I): RagSearchRequest {
    const message = createBaseRagSearchRequest();
    message.query = object.query ?? "";
    message.topK = object.topK ?? 0;
    message.filters = (object.filters !== undefined && object.filters !== null)
      ? RagSearchFilters.fromPartial(object.filters)
      : undefined;
    message.principal = (object.principal !== undefined && object.principal !== null)
      ? Principal.fromPartial(object.principal)
      : undefined;
    return message;
  },
};

function createBaseChunk(): Chunk {
  return { id: "", documentId: "", content: "", source: "", score: 0, metadata: undefined };
}

export const Chunk: MessageFns<Chunk> = {
  encode(message: Chunk, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    if (message.id !== "") {
      writer.uint32(10).string(message.id);
    }
    if (message.documentId !== "") {
      writer.uint32(18).string(message.documentId);
    }
    if (message.content !== "") {
      writer.uint32(26).string(message.content);
    }
    if (message.source !== "") {
      writer.uint32(34).string(message.source);
    }
    if (message.score !== 0) {
      writer.uint32(41).double(message.score);
    }
    if (message.metadata !== undefined) {
      Struct.encode(Struct.wrap(message.metadata), writer.uint32(50).fork()).join();
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): Chunk {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    const end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseChunk();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.id = reader.string();
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.documentId = reader.string();
          continue;
        }
        case 3: {
          if (tag !== 26) {
            break;
          }

          message.content = reader.string();
          continue;
        }
        case 4: {
          if (tag !== 34) {
            break;
          }

          message.source = reader.string();
          continue;
        }
        case 5: {
          if (tag !== 41) {
            break;
          }

          message.score = reader.double();
          continue;
        }
        case 6: {
          if (tag !== 50) {
            break;
          }

          message.metadata = Struct.unwrap(Struct.decode(reader, reader.uint32()));
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): Chunk {
    return {
      id: isSet(object.id) ? globalThis.String(object.id) : "",
      documentId: isSet(object.documentId)
        ? globalThis.String(object.documentId)
        : isSet(object.document_id)
        ? globalThis.String(object.document_id)
        : "",
      content: isSet(object.content) ? globalThis.String(object.content) : "",
      source: isSet(object.source) ? globalThis.String(object.source) : "",
      score: isSet(object.score) ? globalThis.Number(object.score) : 0,
      metadata: isObject(object.metadata) ? object.metadata : undefined,
    };
  },

  toJSON(message: Chunk): unknown {
    const obj: any = {};
    if (message.id !== "") {
      obj.id = message.id;
    }
    if (message.documentId !== "") {
      obj.documentId = message.documentId;
    }
    if (message.content !== "") {
      obj.content = message.content;
    }
    if (message.source !== "") {
      obj.source = message.source;
    }
    if (message.score !== 0) {
      obj.score = message.score;
    }
    if (message.metadata !== undefined) {
      obj.metadata = message.metadata;
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<Chunk>, I>>(base?: I): Chunk {
    return Chunk.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<Chunk>, I>>(object: I): Chunk {
    const message = createBaseChunk();
    message.id = object.id ?? "";
    message.documentId = object.documentId ?? "";
    message.content = object.content ?? "";
    message.source = object.source ?? "";
    message.score = object.score ?? 0;
    message.metadata = object.metadata ?? undefined;
    return message;
  },
};

function createBaseRagSearchResponse(): RagSearchResponse {
  return { chunks: [], correlationId: "" };
}

export const RagSearchResponse: MessageFns<RagSearchResponse> = {
  encode(message: RagSearchResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
    for (const v of message.chunks) {
      Chunk.encode(v!, writer.uint32(10).fork()).join();
    }
    if (message.correlationId !== "") {
      writer.uint32(18).string(message.correlationId);
    }
    return writer;
  },

  decode(input: BinaryReader | Uint8Array, length?: number): RagSearchResponse {
    const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
    const end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseRagSearchResponse();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1: {
          if (tag !== 10) {
            break;
          }

          message.chunks.push(Chunk.decode(reader, reader.uint32()));
          continue;
        }
        case 2: {
          if (tag !== 18) {
            break;
          }

          message.correlationId = reader.string();
          continue;
        }
      }
      if ((tag & 7) === 4 || tag === 0) {
        break;
      }
      reader.skip(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): RagSearchResponse {
    return {
      chunks: globalThis.Array.isArray(object?.chunks) ? object.chunks.map((e: any) => Chunk.fromJSON(e)) : [],
      correlationId: isSet(object.correlationId)
        ? globalThis.String(object.correlationId)
        : isSet(object.correlation_id)
        ? globalThis.String(object.correlation_id)
        : "",
    };
  },

  toJSON(message: RagSearchResponse): unknown {
    const obj: any = {};
    if (message.chunks?.length) {
      obj.chunks = message.chunks.map((e) => Chunk.toJSON(e));
    }
    if (message.correlationId !== "") {
      obj.correlationId = message.correlationId;
    }
    return obj;
  },

  create<I extends Exact<DeepPartial<RagSearchResponse>, I>>(base?: I): RagSearchResponse {
    return RagSearchResponse.fromPartial(base ?? ({} as any));
  },
  fromPartial<I extends Exact<DeepPartial<RagSearchResponse>, I>>(object: I): RagSearchResponse {
    const message = createBaseRagSearchResponse();
    message.chunks = object.chunks?.map((e) => Chunk.fromPartial(e)) || [];
    message.correlationId = object.correlationId ?? "";
    return message;
  },
};

/**
 * Stateless retrieval. The server runs a single SQL query that combines
 * vector similarity with the principal's ACL clause — there is no
 * retrieval path that bypasses the ACL filter.
 */
export type RagServiceService = typeof RagServiceService;
export const RagServiceService = {
  search: {
    path: "/apf.ai.v1.RagService/Search" as const,
    requestStream: false as const,
    responseStream: false as const,
    requestSerialize: (value: RagSearchRequest): Buffer => Buffer.from(RagSearchRequest.encode(value).finish()),
    requestDeserialize: (value: Buffer): RagSearchRequest => RagSearchRequest.decode(value),
    responseSerialize: (value: RagSearchResponse): Buffer => Buffer.from(RagSearchResponse.encode(value).finish()),
    responseDeserialize: (value: Buffer): RagSearchResponse => RagSearchResponse.decode(value),
  },
} as const;

export interface RagServiceServer extends UntypedServiceImplementation {
  search: handleUnaryCall<RagSearchRequest, RagSearchResponse>;
}

export interface RagServiceClient extends Client {
  search(
    request: RagSearchRequest,
    callback: (error: ServiceError | null, response: RagSearchResponse) => void,
  ): ClientUnaryCall;
  search(
    request: RagSearchRequest,
    metadata: Metadata,
    callback: (error: ServiceError | null, response: RagSearchResponse) => void,
  ): ClientUnaryCall;
  search(
    request: RagSearchRequest,
    metadata: Metadata,
    options: Partial<CallOptions>,
    callback: (error: ServiceError | null, response: RagSearchResponse) => void,
  ): ClientUnaryCall;
}

export const RagServiceClient = makeGenericClientConstructor(RagServiceService, "apf.ai.v1.RagService") as unknown as {
  new (address: string, credentials: ChannelCredentials, options?: Partial<ClientOptions>): RagServiceClient;
  service: typeof RagServiceService;
  serviceName: string;
};

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;

type DeepPartial<T> = T extends Builtin ? T
  : T extends Long ? string | number | Long : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
  : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
  : T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
  : Partial<T>;

type KeysOfUnion<T> = T extends T ? keyof T : never;
type Exact<P, I extends P> = P extends Builtin ? P
  : P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };

function isObject(value: any): boolean {
  return typeof value === "object" && value !== null;
}

function isSet(value: any): boolean {
  return value !== null && value !== undefined;
}

interface MessageFns<T> {
  encode(message: T, writer?: BinaryWriter): BinaryWriter;
  decode(input: BinaryReader | Uint8Array, length?: number): T;
  fromJSON(object: any): T;
  toJSON(message: T): unknown;
  create<I extends Exact<DeepPartial<T>, I>>(base?: I): T;
  fromPartial<I extends Exact<DeepPartial<T>, I>>(object: I): T;
}
