import { assertEquals, assertExists } from '@std/assert';
import { SmartMongo } from '@push.rocks/smartmongo';
import { SmartdataDb, SmartDataDbDoc, Collection, svDb, unI } from '@push.rocks/smartdata';

Deno.test({
  name: 'TsmDb spike: SmartMongo + SmartdataDb roundtrip',
  sanitizeOps: false,
  sanitizeResources: false,
  fn: async () => {
    // 1. Start local MongoDB-compatible server
    const mongo = await SmartMongo.createAndStart();
    const mongoDescriptor = await mongo.getMongoDescriptor();
    assertExists(mongoDescriptor.mongoDbUrl);

    // 2. Connect smartdata
    const smartDb = new SmartdataDb({
      mongoDbUrl: mongoDescriptor.mongoDbUrl,
      mongoDbName: 'gitops_spike_test',
    });
    await smartDb.init();
    assertEquals(smartDb.status, 'connected');

    // 3. Define a simple document class
    @Collection(() => smartDb)
    class TestDoc extends SmartDataDbDoc<TestDoc, TestDoc> {
      @unI()
      public id: string = '';

      @svDb()
      public label: string = '';

      @svDb()
      public value: number = 0;

      constructor() {
        super();
      }
    }

    // 4. Insert a document
    const doc = new TestDoc();
    doc.id = 'test-1';
    doc.label = 'spike';
    doc.value = 42;
    await doc.save();

    // 5. Query it back
    const found = await TestDoc.getInstance({ id: 'test-1' });
    assertExists(found);
    assertEquals(found.label, 'spike');
    assertEquals(found.value, 42);

    // 6. Cleanup — smartDb closes; mongo.stop() may hang under Deno, so fire-and-forget
    await smartDb.close();
    mongo.stop().catch(() => {});
  },
});
