/**
 * 텍스트 검색과 벡터 검색을 결합하여 검색 정확도와 포괄성을 동시에 확보합니다.
 * FTS5 전문 검색과 벡터 유사도 검색을 병렬로 수행하여 각각의 장점을 활용합니다.
 */
import Database from 'better-sqlite3';
import type { EmbeddingProvider, MemorySearchFilters, MemoryType } from '../../../shared/types/index.js';
import type { ScoreBreakdown } from '../../../shared/types/search.types.js';
import { UnifiedEmbeddingService } from '../../embedding/services/unified-embedding-service.js';
import { type SearchBySimilarityOutcome, type VectorSearchResult } from '../../memory/services/memory-embedding-service.js';
import { RelationGraph } from '../../relation/services/relation-graph.js';
export interface ITextSearchEngine {
    search(db: Database.Database, query: {
        query: string;
        filters?: MemorySearchFilters;
        limit?: number;
        omit_feedback_in_ranking?: boolean;
    }): Promise<{
        items: unknown[];
        total_count: number;
        query_time: number;
    }>;
}
export interface IEmbeddingService {
    isAvailable(): boolean;
    searchBySimilarity(db: Database.Database, query: string, options: {
        type?: MemoryType[];
        limit?: number;
        threshold?: number;
    }): Promise<VectorSearchResult[] | SearchBySimilarityOutcome>;
    getEmbeddingStats(db: Database.Database): Promise<unknown>;
}
/**
 * 하이브리드 검색의 쿼리 벡터 생성에 사용할 UnifiedEmbeddingService를 결정한다.
 * MemoryEmbeddingService 및 동일 패턴의 주입 구현체는 getUnifiedEmbeddingService()로
 * 인덱싱·검색과 동일한 인스턴스를 노출한다. 그렇지 않을 때만 기본 UnifiedEmbeddingService를 만든다.
 */
export declare function resolveQueryUnifiedEmbeddingForHybridSearch(embeddingService: IEmbeddingService): UnifiedEmbeddingService;
export interface IVectorSearchEngine {
    initialize(db: Database.Database): void;
    getIndexStatus(): {
        available: boolean;
    };
    search(vector: number[], options: {
        limit?: number;
        threshold?: number;
        types?: MemoryType[];
        includeContent?: boolean;
    }, provider?: string): Promise<Array<{
        memory_id: string;
        content: string;
        type: string;
        importance: number;
        created_at: string;
        similarity: number;
    }>>;
}
export interface ISearchResultCombiner {
    combine(textResults: unknown[], vectorResults: VectorSearchResult[], textWeight: number, vectorWeight: number): HybridSearchResult[];
}
/**
 * Procedural Memory 매칭을 수행하는 인터페이스
 * workflow_name, skill_name, trigger_conditions와 쿼리/필터를 매칭하여 부스트 가중치를 결정합니다.
 */
export interface IProceduralMemoryMatcher {
    /**
     * Given: 데이터베이스와 메모리 ID 목록, 검색 쿼리가 제공됨
     * When: Procedural Memory 항목들을 조회하고 쿼리/필터와 매칭함
     * Then: 각 메모리 ID에 대한 매칭 결과를 반환함
     *
     * @param db - 데이터베이스 연결
     * @param memoryIds - 매칭할 메모리 ID 목록
     * @param query - 검색 쿼리 (선택적)
     * @returns 각 메모리 ID에 대한 매칭 결과 맵
     */
    fetchProceduralMemoryMatches(db: Database.Database, memoryIds: string[], query?: HybridSearchQuery): Map<string, {
        workflow_name_match: boolean;
        skill_name_match: boolean;
        trigger_conditions_match: boolean;
    }>;
}
export interface IAdaptiveWeightCalculator {
    calculateWeights(query: string, vectorWeight: number, textWeight: number): {
        vectorWeight: number;
        textWeight: number;
    };
}
export interface ISearchLogger {
    logSearchStart(searchId: string, query: HybridSearchQuery): void;
    logSearchStep(searchId: string, step: string, data: unknown): void;
    logSearchComplete(searchId: string, result: {
        items: unknown[];
        total_count: number;
    }, queryTime: number): void;
    logSearchError(searchId: string, error: unknown, query: HybridSearchQuery): void;
    logExperiment?(searchId: string, experimentId: string, variant: Record<string, unknown>): void;
}
export declare enum SearchErrorType {
    EMBEDDING_GENERATION_FAILED = "EMBEDDING_GENERATION_FAILED",
    VECTOR_SEARCH_FAILED = "VECTOR_SEARCH_FAILED",
    TEXT_SEARCH_FAILED = "TEXT_SEARCH_FAILED",
    RESULT_COMBINATION_FAILED = "RESULT_COMBINATION_FAILED",
    DATABASE_CONNECTION_FAILED = "DATABASE_CONNECTION_FAILED",
    INVALID_QUERY = "INVALID_QUERY",
    SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE"
}
export declare class SearchError extends Error {
    type: SearchErrorType;
    originalError?: Error | undefined;
    context?: unknown | undefined;
    constructor(type: SearchErrorType, message: string, originalError?: Error | undefined, context?: unknown | undefined);
}
export { SearchResultCombiner } from './search-result-combiner.js';
export declare class AdaptiveWeightCalculator implements IAdaptiveWeightCalculator {
    private adaptiveWeights;
    calculateWeights(query: string, vectorWeight: number, textWeight: number): {
        vectorWeight: number;
        textWeight: number;
    };
    private analyzeQuery;
    private normalizeQuery;
}
export declare class SearchLogger implements ISearchLogger {
    logSearchStart(_searchId: string, _query: HybridSearchQuery): void;
    logSearchStep(searchId: string, step: string, data: unknown): void;
    logSearchComplete(_searchId: string, _result: {
        items: unknown[];
        total_count: number;
    }, _queryTime: number): void;
    logSearchError(_searchId: string, _error: unknown, _query: HybridSearchQuery): void;
    /**
     * A/B 테스트를 통해 검색 알고리즘의 효과를 측정하고 개선합니다.
     * 실험 ID와 변이 파라미터를 로깅하여 데이터 기반 의사결정을 지원합니다.
     */
    logExperiment(_searchId: string, _experimentId: string, _variant: Record<string, unknown>): void;
}
/**
 * 구조화된 컨텍스트 정보
 * PRD 요구사항: trigger_conditions와 매칭하기 위한 현재 컨텍스트
 */
export interface TriggerContext {
    tool_name?: string;
    error_type?: string;
    params?: Record<string, unknown>;
    [key: string]: unknown;
}
export interface HybridSearchQuery {
    query: string;
    filters?: MemorySearchFilters | undefined;
    limit?: number | undefined;
    vectorWeight?: number | undefined;
    textWeight?: number | undefined;
    includeRelations?: boolean;
    experiment_id?: string;
    provider_filter?: EmbeddingProvider[];
    match_trigger_conditions?: boolean;
    context?: TriggerContext;
    /** true이면 각 결과에 score_breakdown(기여 점수 + 최종 점수 대비 pct) 포함 */
    include_score_breakdown?: boolean;
}
export interface HybridSearchResult {
    id: string;
    content: string;
    type: string;
    importance: number;
    created_at: string;
    last_accessed?: string | undefined;
    pinned: boolean;
    tags?: string[] | undefined;
    textScore: number;
    vectorScore: number;
    finalScore: number;
    recall_reason: string;
    consolidation_score?: number;
    relation_weight?: number;
    relations?: Array<{
        target_id: string;
        relation_type: string;
        confidence: number;
    }>;
    score_breakdown?: ScoreBreakdown;
    project_id?: string | null;
}
export declare class HybridSearchEngine {
    private textSearchEngine;
    private embeddingService;
    private vectorSearchEngine;
    private resultCombiner;
    private weightCalculator;
    private logger;
    private queryEmbeddingService;
    private readonly defaultVectorWeight;
    private readonly defaultTextWeight;
    private searchStats;
    private ranking;
    private relationGraph;
    private proceduralMemoryMatcher;
    constructor(textSearchEngine: ITextSearchEngine, embeddingService: IEmbeddingService, vectorSearchEngine: IVectorSearchEngine, resultCombiner: ISearchResultCombiner, weightCalculator: IAdaptiveWeightCalculator, logger: ISearchLogger, queryEmbeddingService?: UnifiedEmbeddingService, relationGraph?: RelationGraph, proceduralMemoryMatcher?: IProceduralMemoryMatcher, rankingWeightsPath?: string);
    /**
     * 관계 그래프를 주입하여 관계 기반 검색 기능을 활성화합니다.
     * 선택적으로 설정하여 관계 그래프가 없는 환경에서도 동작하도록 합니다.
     */
    setRelationGraph(relationGraph: RelationGraph | null): void;
    /**
     * 텍스트 검색과 벡터 검색을 병렬로 실행하고 결과를 결합하여 최적의 검색 결과를 제공합니다.
     * 쿼리 특성에 따라 적응형 가중치를 적용하여 검색 정확도를 향상시키기 위해
     */
    search(db: Database.Database, query: HybridSearchQuery): Promise<{
        items: HybridSearchResult[];
        total_count: number;
        query_time: number;
        text_count?: number;
        vector_count?: number;
        fallback_used?: boolean;
        /** 이번 검색에서 쿼리 임베딩에 실제 사용된 provider (VEC 다중 provider 검색 시 복수 가능, 정렬·중복 제거) */
        query_embedding_providers?: EmbeddingProvider[];
        /**
         * VEC(sqlite-vec) 경로에서 고차원 provider를 요청했으나 쿼리 임베딩이 TF-IDF로 생성된 경우(차원 불일치·fallback 등).
         * fallback_used가 false여도 true일 수 있음.
         */
        tfidf_query_embedding_fallback?: boolean;
        /** 위 상황에서 TF-IDF로 바뀐 **요청** provider 목록(진단용, 중복 제거·정렬) */
        tfidf_query_embedding_fallback_providers?: EmbeddingProvider[];
    }>;
    private generateSearchId;
    private logRankingExperimentIfApplicable;
    private calculateAdaptiveWeights;
    private executeTextSearch;
    private executeVectorSearch;
    /**
     * 벡터 검색 실행 (다중 provider 지원)
     *
     * @param db - 데이터베이스 연결
     * @param query - 하이브리드 검색 쿼리
     * @param searchId - 검색 ID (로깅용)
     * @param startTime - 시작 시간 (성능 측정용)
     * @returns 벡터 검색 결과 배열
     */
    private executeVecSearch;
    /**
     * Provider 필터링
     *
     * @param detectedProviders - 감지된 모든 provider 목록
     * @param providerFilter - 필터링할 provider 목록 (선택적, 빈 배열이면 undefined로 처리되어 모든 provider 검색)
     * @param searchId - 검색 ID (로깅용)
     * @returns 필터링된 provider 목록
     */
    private filterProvidersToSearch;
    private getProviderVectorSearchDeps;
    /**
     * 결과 정규화 및 중복 제거
     * Provider별로 Min-Max 정규화를 수행하고, 중복된 memory_id는 최고 점수만 유지
     *
     * @param allResults - 모든 provider의 검색 결과
     * @returns 정규화 및 중복 제거된 결과 배열
     */
    private normalizeAndDeduplicateResults;
    /**
     * Provider별로 결과 그룹화
     */
    private groupResultsByProvider;
    /**
     * Provider별로 Min-Max 정규화 수행
     */
    private normalizeResultsByProvider;
    /**
     * 중복 제거 (memory_id 기준, 정규화된 점수 중 최고 점수만 유지)
     * Provider별 정규화된 결과를 처리하는 전용 메서드입니다.
     */
    private deduplicateNormalizedResults;
    /**
     * 정규화된 점수로 재랭킹
     */
    private rankResults;
    /**
     * Fallback 벡터 검색 실행
     * 벡터 인덱스가 사용 불가능한 경우 임베딩 서비스를 직접 사용하여 검색
     *
     * @param db - 데이터베이스 연결
     * @param query - 하이브리드 검색 쿼리
     * @param searchId - 검색 ID (로깅용)
     * @param _startTime - 시작 시간 (성능 측정용, 현재는 사용하지 않음)
     * @returns 벡터 검색 결과 배열
     */
    private executeFallbackSearch;
    /**
     * Provider 목록 캐시 (메모리 캐시)
     * Provider 목록은 자주 변경되지 않으므로 캐싱하여 성능 개선
     */
    private providerCache;
    /**
     * Provider 캐시 TTL (밀리초)
     * 5분간 캐시 유지
     */
    private static readonly PROVIDER_CACHE_TTL_MS;
    /**
     * 데이터베이스에 저장된 모든 임베딩 provider를 감지하여 사용 가능한 검색 방법을 파악합니다.
     * 모든 provider 목록을 반환하고 count 내림차순으로 정렬하여 주요 provider를 우선 확인합니다.
     * 캐싱을 사용하여 반복적인 데이터베이스 조회를 줄이고 성능을 개선합니다.
     */
    private detectAllStoredEmbeddingProviders;
    /**
     * 쿼리 임베딩 벡터 생성
     * preferredProvider가 지정된 경우 해당 provider로만 임베딩 생성
     * 각 provider는 서로 다른 차원의 임베딩을 사용할 수 있으므로 fallback을 사용하지 않음
     *
     * @param query - 검색 쿼리 문자열
     * @param searchId - 검색 ID (로깅용)
     * @param preferredProvider - 선호하는 임베딩 provider (필수, 각 provider별로 다른 차원의 임베딩 필요)
     * @returns 임베딩 벡터와 실제 사용된 provider (preferred unavailable 시 fallback provider로 생성될 수 있음)
     * @throws SearchError - 임베딩 생성 실패 시
     */
    private generateQueryVector;
    /**
     * Given: 검색 결과들과 관계 가중치, 통합 점수, Procedural Memory 매칭 정보
     * When: normalizeScores()가 호출됨
     * Then: 각 결과의 finalScore가 정규화됨
     *
     * 점수 정규화 로직을 별도 메서드로 분리하여 combineAndSortResults()의 복잡도를 감소시킵니다.
     */
    /**
     * Given: 텍스트 검색 결과와 벡터 검색 결과, 가중치
     * When: mergeResults()가 호출됨
     * Then: 결과가 올바르게 병합됨
     *
     * 결과 병합 로직을 별도 메서드로 분리하여 combineAndSortResults()의 복잡도를 감소시킵니다.
     */
    /**
     * Given: 중복된 ID를 가진 검색 결과 배열
     * When: deduplicateResults()가 호출됨
     * Then: 중복이 제거되고 더 높은 finalScore를 가진 결과가 유지됨
     *
     * 중복 제거 로직을 별도 메서드로 분리하여 combineAndSortResults()의 복잡도를 감소시킵니다.
     * 방어적 프로그래밍 차원에서 추가적인 중복 제거를 수행합니다.
     */
    private deduplicateResults;
    /**
     * Given: 검색 결과 배열
     * When: sortByFinalScore()가 호출됨
     * Then: 결과가 finalScore 내림차순으로 정렬됨
     *
     * 정렬 로직을 별도 메서드로 분리하여 combineAndSortResults()의 복잡도를 감소시킵니다.
     */
    private sortByFinalScore;
    private mergeResults;
    private normalizeScores;
    /**
     * Given: 텍스트 검색 결과, 벡터 검색 결과, 가중치, 제한 개수, 데이터베이스, 옵션
     * When: combineAndSortResults()가 호출됨
     * Then: 병합, 정규화, 중복 제거, 정렬된 검색 결과를 반환함
     *
     * 검색 결과를 병합하고 정렬하는 메인 메서드입니다.
     * 분리된 메서드들(mergeResults, normalizeScores, deduplicateResults, sortByFinalScore)을 조합하여 사용합니다.
     */
    private combineAndSortResults;
    /**
     * 데이터베이스에서 consolidation_score 조회
     */
    private fetchConsolidationScores;
    private fetchFeedbackScores;
    private fetchProcessAttributeContext;
    private buildRankingContext;
    /**
     * 관계 가중치 계산 및 조회
     * 관계 정보도 함께 반환 (선택적)
     */
    private fetchRelationWeights;
    /**
     * 최근성 점수 계산 (간단한 구현)
     */
    private calculateRecency;
    /**
     * 사용성 점수 계산 (간단한 구현)
     */
    private calculateUsage;
    private calculateQueryTime;
    /**
     * 검색 통계 업데이트
     */
    private updateSearchStats;
    private normalizeQuery;
    /**
     * 검색 통계 정보
     */
    getSearchStats(db: Database.Database): Promise<{
        textSearchAvailable: boolean;
        vectorSearchAvailable: boolean;
        embeddingStats: unknown;
        searchStats: Map<string, {
            textHits: number;
            vectorHits: number;
            totalSearches: number;
        }>;
    }>;
    /**
     * 임베딩 서비스 사용 가능 여부 확인
     */
    isEmbeddingAvailable(): boolean;
}
export declare function createHybridSearchEngine(textSearchEngine?: ITextSearchEngine, embeddingService?: IEmbeddingService, vectorSearchEngine?: IVectorSearchEngine, resultCombiner?: ISearchResultCombiner, weightCalculator?: IAdaptiveWeightCalculator, logger?: ISearchLogger): HybridSearchEngine;
export declare function getHybridSearchEngine(): HybridSearchEngine;
//# sourceMappingURL=hybrid-search-engine.d.ts.map