/**
 * Sequelize Framework Security Model
 *
 * Sequelize ORM methods (findAll, findOne, create, update, destroy) are
 * parameterised by default. Raw queries with template literals are unsafe.
 */

import type { FrameworkSecurityModel } from './types'

// Safe ORM patterns
const SEQUELIZE_ORM_RE = /\.(findAll|findOne|findByPk|findOrCreate|create|update|destroy|bulkCreate|count|sum|max|min)\s*\(/
const SEQUELIZE_REPLACEMENTS_RE = /sequelize\.query\s*\([^)]*replacements\s*:/

// Unsafe raw query patterns
const SEQUELIZE_RAW_TEMPLATE_RE = /sequelize\.query\s*\(\s*`/
const SEQUELIZE_RAW_CONCAT_RE = /sequelize\.query\s*\([^)]*\+/
const SEQUELIZE_LITERAL_RE = /Sequelize\.literal\s*\(/

export const sequelizeModel: FrameworkSecurityModel = {
  framework: 'sequelize',

  safePatterns: [
    {
      id: 'orm_sequelize_parameterised',
      suppressesCategory: ['sql_injection', 'dangerous_function'],
      detect: (line: string, _filePath: string, _fileContent: string) => SEQUELIZE_ORM_RE.test(line),
      reason: 'Sequelize ORM methods use parameterised queries — SQL injection not applicable',
    },
    {
      id: 'orm_sequelize_replacements',
      suppressesCategory: ['sql_injection'],
      detect: (line: string, _filePath: string, _fileContent: string) => SEQUELIZE_REPLACEMENTS_RE.test(line),
      reason: 'sequelize.query() with replacements is parameterised — SQL injection mitigated',
    },
  ],

  unsafePatterns: [
    {
      id: 'sequelize_raw_template',
      boostsCategory: ['sql_injection'],
      detect: (line: string, _filePath: string, _fileContent: string) => {
        if (SEQUELIZE_REPLACEMENTS_RE.test(line)) return false
        return SEQUELIZE_RAW_TEMPLATE_RE.test(line)
      },
      reason: 'sequelize.query() with template literal is raw SQL — NOT parameterised',
    },
    {
      id: 'sequelize_raw_concat',
      boostsCategory: ['sql_injection'],
      detect: (line: string, _filePath: string, _fileContent: string) => {
        if (SEQUELIZE_REPLACEMENTS_RE.test(line)) return false
        return SEQUELIZE_RAW_CONCAT_RE.test(line)
      },
      reason: 'sequelize.query() with string concatenation is raw SQL — NOT parameterised',
    },
    {
      id: 'sequelize_literal_injection',
      boostsCategory: ['sql_injection'],
      detect: (line: string, _filePath: string, _fileContent: string) => SEQUELIZE_LITERAL_RE.test(line),
      reason: 'Sequelize.literal() injects raw SQL expressions — injection risk with user input',
    },
  ],
}
