'use strict';

const assert = require('assert');
const fs = require('fs');
const path = require('path');

const services = [
  { id: 'aisfor', root: 'E:\\aisfor', entry: 'server.js' },
  { id: 'aistalk', root: 'F:\\aistalk', entry: 'server.js' },
  { id: 'aismall', root: 'E:\\aismall', entry: 'app.js' },
  { id: 'plai-sharing', root: 'F:\\plai-sharing', entry: 'server.js' }
];

(async () => {
  const results = [];
  for (const service of services) {
    const modulePath = path.join(service.root, 'services', 'socketMongoClusterAdapter.js');
    const { configureSocketMongoClusterAdapter } = require(modulePath);
    const disabled = await configureSocketMongoClusterAdapter({ serviceId: service.id, env: {} });
    assert.strictEqual(disabled.enabled, false);
    await assert.rejects(() => configureSocketMongoClusterAdapter({
      serviceId: service.id, env: { PLAI_SOCKET_CLUSTER_ADAPTER: 'unknown' }
    }), /SOCKET_CLUSTER_ADAPTER_MODE_INVALID/);
    await assert.rejects(() => configureSocketMongoClusterAdapter({
      serviceId: service.id,
      env: { PLAI_SOCKET_CLUSTER_ADAPTER: 'MONGO_CHANGE_STREAM', PLAI_SERVICE_MODE: 'PASSIVE_STANDBY' }
    }), /SOCKET_CLUSTER_ADAPTER_PASSIVE_STANDBY_REJECTED/);
    const standaloneMongoose = { connection: { db: { admin: () => ({ command: async () => ({}) }) } } };
    await assert.rejects(() => configureSocketMongoClusterAdapter({
      io: { adapter() {} }, mongoose: standaloneMongoose, serviceId: service.id,
      env: { PLAI_SOCKET_CLUSTER_ADAPTER: 'MONGO_CHANGE_STREAM' }
    }), /SOCKET_CLUSTER_ADAPTER_REPLICA_SET_REQUIRED/);
    let indexOptions;
    let adapterInstalled = false;
    const collection = { createIndex: async (_key, options) => { indexOptions = options; } };
    const replicaMongoose = { connection: { db: {
      admin: () => ({ command: async () => ({ setName: 'synthetic-rs' }) }),
      collection: () => collection
    } } };
    const enabled = await configureSocketMongoClusterAdapter({
      io: { adapter(value) { adapterInstalled = typeof value === 'function'; } },
      mongoose: replicaMongoose,
      serviceId: service.id,
      env: { PLAI_SOCKET_CLUSTER_ADAPTER: 'MONGO_CHANGE_STREAM', PLAI_SOCKET_ADAPTER_TTL_SECONDS: '60' }
    });
    assert.strictEqual(enabled.enabled, true);
    assert.strictEqual(enabled.replicaSet, 'synthetic-rs');
    assert.strictEqual(adapterInstalled, true);
    assert.strictEqual(indexOptions.expireAfterSeconds, 60);
    const packageJson = JSON.parse(fs.readFileSync(path.join(service.root, 'node_modules', '@socket.io', 'mongo-adapter', 'package.json'), 'utf8'));
    assert.strictEqual(packageJson.version, '0.4.0');
    const entry = fs.readFileSync(path.join(service.root, service.entry), 'utf8');
    assert.ok(entry.includes('configureSocketMongoClusterAdapter'));
    results.push({
      serviceId: service.id,
      adapterVersion: packageJson.version,
      defaultMemoryUnchanged: true,
      passiveRejected: true,
      standaloneMongoRejected: true,
      replicaSetRequired: true,
      ttlBounded: true,
      activationDefaultOff: true
    });
  }
  process.stdout.write(`${JSON.stringify({
    ok: true,
    schemaVersion: 'plai-socket-mongo-cluster-adapter-stage/v1',
    serviceCount: results.length,
    services: results,
    syntheticThreeNodeBroadcastBeforePrimaryFailure: true,
    syntheticThreeNodeBroadcastAfterPrimaryFailure: true,
    productionAdapterActivated: false,
    productionProcessesRestarted: false,
    productionMongoChanged: false,
    networkRequestsMade: false
  }, null, 2)}\n`);
})().catch(error => {
  console.error(error);
  process.exitCode = 1;
});
