/**
 * ESLint rules for Client-Only Guardrails
 * 
 * Enforces client-side only boundaries
 */

module.exports = {
  // Rule 1: No server-side code in client-only files
  'no-server-code-in-client-only': {
    meta: {
      type: 'problem',
      docs: {
        description: 'Forbid server-side code in client-only files',
        category: 'Client-Only',
      },
      messages: {
        message: 'Client-only files cannot contain server-side code - see apps/website/lib/contracts/view-models/ViewModel.ts',
      },
    },
    create(context) {
      return {
        Program(node) {
          const filename = context.getFilename();
          if (filename.includes('/app/') && 
              filename.endsWith('.tsx') &&
              !filename.endsWith('page.tsx') &&
              !filename.endsWith('layout.tsx')) {
            
            const sourceCode = context.getSourceCode();
            const text = sourceCode.getText();
            
            // Check for server-side patterns
            const serverPatterns = [
              /getServerSideProps/,
              /cookies\(\)/,
              /headers\(\)/,
              /next\/headers/,
            ];
            
            for (const pattern of serverPatterns) {
              if (pattern.test(text)) {
                context.report({
                  loc: { line: 1, column: 0 },
                  messageId: 'message',
                });
                break;
              }
            }
          }
        },
      };
    },
  },

  // Rule 2: Client-only files must have 'use client' directive
  'client-only-must-have-directive': {
    meta: {
      type: 'problem',
      docs: {
        description: 'Enforce use client directive',
        category: 'Client-Only',
      },
      messages: {
        message: 'Client-only files must have "use client" directive at the top - see apps/website/lib/contracts/view-models/ViewModel.ts',
      },
    },
    create(context) {
      return {
        Program(node) {
          const filename = context.getFilename();
          if (filename.includes('/app/') &&
              filename.endsWith('.tsx') &&
              !filename.endsWith('page.tsx') &&
              !filename.endsWith('layout.tsx')) {
            
            const sourceCode = context.getSourceCode();
            
            // Check for 'use client' as a string literal directive
            // This can be either a comment or a string literal statement
            const comments = sourceCode.getAllComments();
            const firstComment = comments[0];
            
            let hasDirective = false;
            
            // Check if it's a comment
            if (firstComment &&
                firstComment.type === 'Line' &&
                (firstComment.value.trim() === '"use client"' ||
                 firstComment.value.trim() === 'use client')) {
              hasDirective = true;
            }
            
            // Check if it's a string literal statement (the actual Next.js way)
            if (!hasDirective && node.body.length > 0) {
              const firstStmt = node.body[0];
              if (firstStmt &&
                  firstStmt.type === 'ExpressionStatement' &&
                  firstStmt.expression.type === 'Literal' &&
                  (firstStmt.expression.value === 'use client' ||
                   firstStmt.expression.value === '"use client"')) {
                hasDirective = true;
              }
            }
            
            if (!hasDirective) {
              context.report({
                loc: { line: 1, column: 0 },
                messageId: 'message',
              });
            }
          }
        },
      };
    },
  },
};