import type { Lix } from "../lix/open-lix.js";
import type { LixVersion } from "./schema-definition.js";
import { type SelectQueryBuilder } from "kysely";
export type DiffRow = {
    entity_id: string;
    schema_key: string;
    file_id: string;
    before_version_id: string | null;
    before_change_id: string | null;
    before_commit_id: string | null;
    after_version_id: string | null;
    after_change_id: string | null;
    after_commit_id: string | null;
    status: "added" | "modified" | "removed" | "unchanged";
};
/**
 * Compares two versions and returns differences between their entities.
 *
 * This function is modeled for merging a source version into a target version,
 * which is why the source always wins in conflict scenarios (when both versions
 * modified the same entity). It performs a full outer join between source and
 * target versions to identify added, modified, removed, and unchanged entities.
 *
 * Note: More sophisticated diff strategies and proper conflict handling are
 * planned for the future. Please upvote https://github.com/opral/lix-sdk/issues/368
 * if you need conflict detection and resolution capabilities.
 *
 * The returned query builder allows for flexible filtering and composition
 * before executing the diff. When no target is specified, compares against
 * the active version.
 *
 * Diff status meanings:
 * - `added`: Entity exists only in source version (new addition)
 * - `removed`: Entity explicitly deleted in source (tombstone present)
 * - `modified`: Entity exists in both but with different change_ids (source wins)
 * - `unchanged`: Entity has same change_id in both OR exists only in target without explicit deletion
 *
 * Visual representation (source → target):
 * ```
 * Status      | Source | Target | before_version_id | after_version_id | before_* | after_*
 * ------------|--------|--------|-------------------|------------------|----------|----------
 * added       |   ✓    |   ✗    |       null        |    source.id     |   null   | source
 * removed     |   ✓*   |   ✓    |     target.id     |    source.id     |  target  | tombstone
 * modified    |   ✓    |   ✓    |     target.id     |    source.id     |  target  | source
 * unchanged   |   ✓    |   ✓    |     target.id     |    source.id     |   same   | same
 * unchanged   |   ✗    |   ✓    |     target.id     |     target.id    |  target  | target
 * ```
 * * Source ✓* indicates a tombstone (explicit deletion)
 *
 * Performance tips:
 * - Filter by status to exclude unchanged entities (most common)
 * - Filter by file_id when diffing specific documents
 * - Filter by schema_key when interested in specific entity types
 *
 * @example
 * // Get all changes between two versions
 * const changes = await selectVersionDiff({ lix, source, target })
 *   .where('diff.status', '!=', 'unchanged')
 *   .execute();
 *
 * @example
 * // Compare specific file between source and active version
 * const fileDiff = await selectVersionDiff({ lix, source })
 *   .where('diff.file_id', '=', 'file1.json')
 *   .where('diff.status', '!=', 'unchanged')
 *   .orderBy('diff.entity_id')
 *   .execute();
 *
 * @example
 * // Get only entities of a specific schema that were modified
 * const schemaDiff = await selectVersionDiff({ lix, source, target })
 *   .where('diff.schema_key', '=', 'message')
 *   .where('diff.status', 'in', ['added', 'modified', 'removed'])
 *   .execute();
 *
 * @example
 * // Find entities that exist only in target (no explicit delete in source)
 * const targetOnly = await selectVersionDiff({ lix, source, target })
 *   .where('diff.status', '=', 'unchanged')
 *   .whereRef('diff.after_version_id', '=', 'diff.before_version_id')
 *   .execute();
 *
 * @example
 * // Check if specific entities changed
 * const entityDiff = await selectVersionDiff({ lix, source, target })
 *   .where('diff.entity_id', 'in', ['entity1', 'entity2', 'entity3'])
 *   .where('diff.status', '!=', 'unchanged')
 *   .execute();
 *
 * if (entityDiff.length > 0) {
 *   // Some entities changed
 * }
 *
 * ## Understanding Common Ancestor Behavior
 *
 * Imagine you and a colleague both start from the same document (common ancestor):
 * - You create a "source" version and make changes
 * - Your colleague creates a "target" version and makes different changes
 *
 * When comparing these versions, the diff needs to know:
 * 1. What did YOU intentionally delete? (will be removed from target)
 * 2. What did your colleague add that you never knew about? (will be kept)
 *
 * The system tracks deletions using "tombstones" - special markers that say
 * "this entity was deleted". When you delete something, a tombstone is created.
 *
 * This means:
 * - If you deleted "entity A" that existed in the common ancestor →
 *   Status: "deleted" (tombstone present, will be removed from target)
 * - If "entity B" only exists in target (added after you created your version) →
 *   Status: "unchanged" (no tombstone, you never knew about it, so it stays)
 *
 * Without this logic, the system couldn't tell the difference between
 * "I deleted this" and "I never had this".
 */
export declare function selectVersionDiff(args: {
    lix: Lix;
    source: Pick<LixVersion, "id">;
    target?: Pick<LixVersion, "id">;
}): SelectQueryBuilder<any, "diff", DiffRow>;
//# sourceMappingURL=select-version-diff.d.ts.map