import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { CloudClient } from "chromadb";
import { v4 as uuidv4 } from "uuid";
import { Logger } from "../monitoring/logger.js";
class ChromaDBAdapter {
  client;
  collection = null;
  logger;
  config;
  userId;
  teamId;
  constructor(config, userId, teamId) {
    this.config = config;
    this.userId = userId;
    this.teamId = teamId;
    this.logger = new Logger("ChromaDBAdapter");
    this.client = new CloudClient({
      apiKey: config.apiKey,
      tenant: config.tenant,
      database: config.database
    });
  }
  async initialize() {
    try {
      const collectionName = this.config.collectionName || "stackmemory_contexts";
      this.collection = await this.client.getOrCreateCollection({
        name: collectionName,
        metadata: {
          description: "StackMemory context storage",
          version: "1.0.0",
          created_at: (/* @__PURE__ */ new Date()).toISOString()
        }
      });
      this.logger.info(`ChromaDB collection '${collectionName}' initialized`);
    } catch (error) {
      this.logger.error("Failed to initialize ChromaDB collection", error);
      throw error;
    }
  }
  /**
   * Store a frame in ChromaDB
   */
  async storeFrame(frame) {
    if (!this.collection) {
      throw new Error("ChromaDB not initialized");
    }
    try {
      const frameMetadata = {
        user_id: this.userId,
        frame_id: frame.frameId,
        session_id: frame.sessionId || "unknown",
        project_name: frame.projectName || "default",
        timestamp: frame.timestamp,
        type: "frame",
        score: frame.score,
        tags: frame.tags || []
      };
      if (this.teamId) {
        frameMetadata.team_id = this.teamId;
      }
      const document = {
        id: `frame_${frame.frameId}_${this.userId}`,
        document: this.frameToDocument(frame),
        metadata: frameMetadata
      };
      await this.collection.add({
        ids: [document.id],
        documents: [document.document],
        metadatas: [document.metadata]
      });
      this.logger.debug(
        `Stored frame ${frame.frameId} for user ${this.userId}`
      );
    } catch (error) {
      this.logger.error(`Failed to store frame ${frame.frameId}`, error);
      throw error;
    }
  }
  /**
   * Store a decision or observation
   */
  async storeContext(type, content, metadata) {
    if (!this.collection) {
      throw new Error("ChromaDB not initialized");
    }
    try {
      const contextId = `${type}_${uuidv4()}_${this.userId}`;
      const documentMetadata = {
        user_id: this.userId,
        frame_id: metadata?.frame_id || "none",
        session_id: metadata?.session_id || "unknown",
        project_name: metadata?.project_name || "default",
        timestamp: Date.now(),
        type,
        ...metadata
      };
      if (this.teamId) {
        documentMetadata.team_id = this.teamId;
      }
      const document = {
        id: contextId,
        document: content,
        metadata: documentMetadata
      };
      await this.collection.add({
        ids: [document.id],
        documents: [document.document],
        metadatas: [document.metadata]
      });
      this.logger.debug(`Stored ${type} for user ${this.userId}`);
    } catch (error) {
      this.logger.error(`Failed to store ${type}`, error);
      throw error;
    }
  }
  /**
   * Query contexts by semantic similarity
   */
  async queryContexts(query, limit = 10, filters) {
    if (!this.collection) {
      throw new Error("ChromaDB not initialized");
    }
    try {
      const whereClause = {
        user_id: this.userId
      };
      if (this.teamId) {
        whereClause["$or"] = [
          { team_id: this.teamId },
          { user_id: this.userId }
        ];
      }
      if (filters?.type && filters.type.length > 0) {
        whereClause.type = { $in: filters.type };
      }
      if (filters?.projectName) {
        whereClause.project_name = filters.projectName;
      }
      if (filters?.sessionId) {
        whereClause.session_id = filters.sessionId;
      }
      if (filters?.startTime || filters?.endTime) {
        whereClause.timestamp = {};
        if (filters.startTime) {
          whereClause.timestamp.$gte = filters.startTime;
        }
        if (filters.endTime) {
          whereClause.timestamp.$lte = filters.endTime;
        }
      }
      const results = await this.collection.query({
        queryTexts: [query],
        nResults: limit,
        where: whereClause,
        include: ["documents", "metadatas", "distances"]
      });
      const contexts = [];
      if (results.documents && results.documents[0]) {
        for (let i = 0; i < results.documents[0].length; i++) {
          contexts.push({
            content: results.documents[0][i] || "",
            metadata: results.metadatas?.[0]?.[i] || {},
            distance: results.distances?.[0]?.[i] || 0
          });
        }
      }
      this.logger.debug(`Found ${contexts.length} contexts for query`);
      return contexts;
    } catch (error) {
      this.logger.error("Failed to query contexts", error);
      throw error;
    }
  }
  /**
   * Get user's recent contexts
   */
  async getRecentContexts(limit = 20, type) {
    if (!this.collection) {
      throw new Error("ChromaDB not initialized");
    }
    try {
      const whereClause = {
        user_id: this.userId
      };
      if (type) {
        whereClause.type = type;
      }
      const results = await this.collection.get({
        where: whereClause,
        include: ["documents", "metadatas"]
      });
      const contexts = [];
      if (results.documents) {
        const indexed = results.documents.map((doc, i) => ({
          content: doc || "",
          metadata: results.metadatas?.[i] || {}
        }));
        indexed.sort(
          (a, b) => (b.metadata.timestamp || 0) - (a.metadata.timestamp || 0)
        );
        contexts.push(...indexed.slice(0, limit));
      }
      return contexts;
    } catch (error) {
      this.logger.error("Failed to get recent contexts", error);
      throw error;
    }
  }
  /**
   * Delete old contexts (retention policy)
   */
  async deleteOldContexts(olderThanDays = 30) {
    if (!this.collection) {
      throw new Error("ChromaDB not initialized");
    }
    try {
      const cutoffTime = Date.now() - olderThanDays * 24 * 60 * 60 * 1e3;
      const results = await this.collection.get({
        where: {
          user_id: this.userId,
          timestamp: { $lt: cutoffTime }
        },
        include: ["ids"]
      });
      if (!results.ids || results.ids.length === 0) {
        return 0;
      }
      await this.collection.delete({
        ids: results.ids
      });
      this.logger.info(`Deleted ${results.ids.length} old contexts`);
      return results.ids.length;
    } catch (error) {
      this.logger.error("Failed to delete old contexts", error);
      throw error;
    }
  }
  /**
   * Get team contexts (if user is part of a team)
   */
  async getTeamContexts(limit = 20) {
    if (!this.collection || !this.teamId) {
      return [];
    }
    try {
      const results = await this.collection.get({
        where: {
          team_id: this.teamId
        },
        include: ["documents", "metadatas"],
        limit
      });
      const contexts = [];
      if (results.documents) {
        for (let i = 0; i < results.documents.length; i++) {
          contexts.push({
            content: results.documents[i] || "",
            metadata: results.metadatas?.[i] || {}
          });
        }
      }
      return contexts;
    } catch (error) {
      this.logger.error("Failed to get team contexts", error);
      return [];
    }
  }
  /**
   * Convert frame to searchable document
   */
  frameToDocument(frame) {
    const parts = [
      `Frame: ${frame.title}`,
      `Type: ${frame.type}`,
      `Status: ${frame.status}`
    ];
    if (frame.description) {
      parts.push(`Description: ${frame.description}`);
    }
    if (frame.inputs && frame.inputs.length > 0) {
      parts.push(`Inputs: ${frame.inputs.join(", ")}`);
    }
    if (frame.outputs && frame.outputs.length > 0) {
      parts.push(`Outputs: ${frame.outputs.join(", ")}`);
    }
    if (frame.tags && frame.tags.length > 0) {
      parts.push(`Tags: ${frame.tags.join(", ")}`);
    }
    if (frame.digest_json) {
      try {
        const digest = JSON.parse(frame.digest_json);
        if (digest.summary) {
          parts.push(`Summary: ${digest.summary}`);
        }
        if (digest.keyDecisions) {
          parts.push(`Decisions: ${digest.keyDecisions.join(". ")}`);
        }
      } catch {
      }
    }
    return parts.join("\n");
  }
  /**
   * Update team ID for a user
   */
  async updateTeamId(newTeamId) {
    this.teamId = newTeamId;
    this.logger.info(`Updated team ID to ${newTeamId} for user ${this.userId}`);
  }
  /**
   * Get storage statistics
   */
  async getStats() {
    if (!this.collection) {
      throw new Error("ChromaDB not initialized");
    }
    try {
      const userResults = await this.collection.get({
        where: { user_id: this.userId },
        include: ["metadatas"]
      });
      const stats = {
        totalDocuments: 0,
        userDocuments: userResults.ids?.length || 0,
        documentsByType: {}
      };
      if (userResults.metadatas) {
        for (const metadata of userResults.metadatas) {
          const type = metadata?.type || "unknown";
          stats.documentsByType[type] = (stats.documentsByType[type] || 0) + 1;
        }
      }
      if (this.teamId) {
        const teamResults = await this.collection.get({
          where: { team_id: this.teamId },
          include: ["ids"]
        });
        stats.teamDocuments = teamResults.ids?.length || 0;
      }
      stats.totalDocuments = stats.userDocuments + (stats.teamDocuments || 0);
      return stats;
    } catch (error) {
      this.logger.error("Failed to get stats", error);
      throw error;
    }
  }
}
export {
  ChromaDBAdapter
};
//# sourceMappingURL=chromadb-adapter.js.map
