'use strict';

const QUOTE_CHAR = '"';

function mapType(field) {
  switch (field.type) {
    case 'string':
      return `VARCHAR2(${field.length})`;
    case 'text':
      return 'CLOB';
    case 'integer':
      return 'NUMBER(10)';
    case 'bigint':
      return 'NUMBER(19)';
    case 'decimal':
      return `NUMBER(${field.precision},${field.scale})`;
    case 'boolean':
      return 'VARCHAR2(5)';
    case 'date':
      return 'DATE';
    case 'timestamp':
      return 'TIMESTAMP';
    case 'uuid':
      return 'VARCHAR2(36)';
    case 'json':
      return 'CLOB';
    default:
      throw new Error(`Unknown type: '${field.type}'`);
  }
}

function formatDefault(def) {
  if (def.kind === 'literal') {
    if (typeof def.value === 'boolean') return def.value ? "'true'" : "'false'";
    if (typeof def.value === 'number') return String(def.value);
    if (typeof def.value === 'string') return `'${def.value.replace(/'/g, "''")}'`;
    throw new Error(`Unknown literal type: '${typeof def.value}'`);
  }

  if (def.kind === 'function') {
    if (def.name === 'now') return 'SYSTIMESTAMP';
    throw new Error(`Unknown function: '${def.name}'`);
  }

  if (def.kind === 'constant') {
    if (def.value === 'current_date') return 'CURRENT_DATE';
    throw new Error(`Unknown constant: '${def.value}'`);
  }

  throw new Error(`Unknown default kind: '${def.kind}'`);
}

function quoteIdentifier(identifier) {
  if (typeof identifier !== 'string' || identifier === '') {
    throw new Error('Identifier must be a non-empty string');
  }
  return identifier;
}

function formatTableIdentifier(ir) {
  if (!ir || typeof ir.tableName !== 'string' || ir.tableName === '') {
    throw new Error('formatTableIdentifier: ir.tableName must be a non-empty string');
  }
  // Oracle convention: DDL run as schema owner so prefix is redundant in most setups,
  // tetapi cross-schema notation `<owner>.<table>` valid SQL. Default ikut emit prefix
  // bila schemaName diberikan, konsisten dengan PG/MySQL.
  if (ir.schemaName) {
    return `${quoteIdentifier(ir.schemaName)}.${quoteIdentifier(ir.tableName)}`;
  }
  return quoteIdentifier(ir.tableName);
}

function formatReferentialAction(action) {
  switch (action) {
    case 'cascade': return 'CASCADE';
    case 'restrict': return 'RESTRICT';
    case 'setNull': return 'SET NULL';
    case 'noAction': return 'NO ACTION';
    default:
      throw new Error(`Unknown referential action: '${action}'`);
  }
}

module.exports = {
  name: 'oracle',
  // Oracle 12.2+ supports 128 char identifiers. Pre-12.2 (11g) limit was 30 char.
  // RESTForge target Oracle 19c+ (default COMPATIBLE >= 12.2). Override via
  // --max-name-length=30 if deploying to legacy database.
  maxIdentifierLength: 128,
  // Boolean disimpan sebagai VARCHAR2(5) 'true'/'false'; bukan native.
  nativeBoolean: false,
  mapType,
  formatDefault,
  quoteIdentifier,
  formatTableIdentifier,
  formatReferentialAction
};
