#!/usr/bin/env node

/**
 * Validates a Smart Canvas config JSON against the canvas-config JSON Schema.
 *
 * Uses Ajv for proper JSON Schema 2020-12 validation including $ref, oneOf, const, etc.
 * Reads canvas-config.schema.json (the generated unified schema), falling back to
 * canvas-config.base.schema.json if the unified version hasn't been built yet.
 *
 * Usage: npm run validate-config -- <path/to/config.json>
 */

import Ajv from 'ajv/dist/2020.js';
import addFormats from 'ajv-formats';
import fs from 'fs';
import path from 'path';
import url from 'url';

const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
const schemaDir = path.resolve(__dirname, '../schema');
const unifiedPath = path.join(schemaDir, 'canvas-config.schema.json');
const basePath = path.join(schemaDir, 'canvas-config.base.schema.json');

const usage = () => {
  console.error('Usage: npm run validate-config -- <path/to/config.json>');
};

const targetPath = process.argv[2];
if (!targetPath) {
  usage();
  process.exit(1);
}

// Load the best available schema (unified > base)
let schemaPath;
if (fs.existsSync(unifiedPath)) {
  schemaPath = unifiedPath;
  console.log('Using unified schema (core + adaptive action kinds)');
} else if (fs.existsSync(basePath)) {
  schemaPath = basePath;
  console.log('Using base schema (run npm run generate-schema to include adaptive actions)');
} else {
  console.error('No schema found. Run npm run generate-schema first.');
  process.exit(1);
}

let schema;
try {
  schema = JSON.parse(fs.readFileSync(schemaPath, 'utf-8'));
} catch (err) {
  console.error(`Failed to read schema ${schemaPath}:`, err.message);
  process.exit(1);
}

// Load the config to validate
const configPath = path.resolve(process.cwd(), targetPath);
let config;
try {
  config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
} catch (err) {
  console.error(`Failed to read config ${configPath}:`, err.message);
  process.exit(1);
}

// Compile and validate with Ajv
const ajv = new Ajv({ allErrors: true, strict: false });
addFormats(ajv);

const validate = ajv.compile(schema);
const valid = validate(config);

if (!valid) {
  console.error(`\u274C Config invalid (${validate.errors.length} issue(s)):`);
  for (const err of validate.errors) {
    const location = err.instancePath || '(root)';
    console.error(
      `  - ${location}: ${err.message}${err.params ? ` ${JSON.stringify(err.params)}` : ''}`
    );
  }
  process.exit(1);
}

console.log(`\u2705 ${path.relative(process.cwd(), configPath)} is valid.`);
