/**
 * ESLint rules for Write Boundary Guardrails
 * 
 * Enforces write operation boundaries
 */

module.exports = {
  // Rule 1: No direct mutations in write boundaries
  'no-direct-mutations-in-write-boundaries': {
    meta: {
      type: 'problem',
      docs: {
        description: 'Forbid direct mutations in write boundaries',
        category: 'Write Boundary',
      },
      messages: {
        message: 'Write boundaries must use mutation functions, not direct mutations - see apps/website/lib/contracts/write-boundaries/WriteBoundary.ts',
      },
    },
    create(context) {
      return {
        AssignmentExpression(node) {
          const filename = context.getFilename();
          if (filename.includes('/lib/write-boundaries/')) {
            // Check for direct property assignment
            if (node.left.type === 'MemberExpression' &&
                !isInMutationFunction(node)) {
              context.report({
                node,
                messageId: 'message',
              });
            }
          }
        },
        UpdateExpression(node) {
          const filename = context.getFilename();
          if (filename.includes('/lib/write-boundaries/') &&
              !isInMutationFunction(node)) {
            context.report({
              node,
              messageId: 'message',
            });
          }
        },
      };
    },
  },

  // Rule 2: Write boundaries must use repository pattern
  'write-boundaries-must-use-repository': {
    meta: {
      type: 'problem',
      docs: {
        description: 'Enforce repository pattern in write boundaries',
        category: 'Write Boundary',
      },
      messages: {
        message: 'Write boundaries must use repository pattern for data access - see apps/website/lib/contracts/write-boundaries/WriteBoundary.ts',
      },
    },
    create(context) {
      return {
        CallExpression(node) {
          const filename = context.getFilename();
          if (filename.includes('/lib/write-boundaries/')) {
            // Check for direct database access
            if (node.callee.type === 'MemberExpression' &&
                node.callee.object.type === 'Identifier' &&
                ['db', 'prisma', 'knex'].includes(node.callee.object.name) &&
                !isInComment(node)) {
              context.report({
                node,
                messageId: 'message',
              });
            }
          }
        },
      };
    },
  },
};

// Helper functions
function isInMutationFunction(node) {
  // Check if node is inside a mutation function
  let current = node;
  while (current) {
    if (current.type === 'FunctionDeclaration' || current.type === 'FunctionExpression') {
      const name = current.id?.name || '';
      return name.includes('mutate') || name.includes('update') || name.includes('create');
    }
    current = current.parent;
  }
  return false;
}

function isInComment(node) {
  return false;
}