/**
 * Deployment & Infrastructure Tests
 * Tests for Docker, CI/CD, and deployment configuration
 */

import fs from 'fs'
import path from 'path'

describe('Deployment Configuration', () => {
  describe('Dockerfile', () => {
    it('should have valid Dockerfile', () => {
      const dockerfilePath = path.join(process.cwd(), 'Dockerfile')
      expect(fs.existsSync(dockerfilePath)).toBe(true)
    })

    it('should use Alpine base image', () => {
      const dockerfilePath = path.join(process.cwd(), 'Dockerfile')
      const content = fs.readFileSync(dockerfilePath, 'utf-8')
      expect(content).toContain('alpine')
    })

    it('should have health check configured', () => {
      const dockerfilePath = path.join(process.cwd(), 'Dockerfile')
      const content = fs.readFileSync(dockerfilePath, 'utf-8')
      expect(content).toContain('HEALTHCHECK')
    })

    it('should run as non-root user', () => {
      const dockerfilePath = path.join(process.cwd(), 'Dockerfile')
      const content = fs.readFileSync(dockerfilePath, 'utf-8')
      expect(content).toContain('USER nextjs')
      expect(content).toContain('addgroup')
      expect(content).toContain('adduser')
    })

    it('should expose port 3000', () => {
      const dockerfilePath = path.join(process.cwd(), 'Dockerfile')
      const content = fs.readFileSync(dockerfilePath, 'utf-8')
      expect(content).toContain('EXPOSE 3000')
    })

    it('should use multi-stage build', () => {
      const dockerfilePath = path.join(process.cwd(), 'Dockerfile')
      const content = fs.readFileSync(dockerfilePath, 'utf-8')
      expect(content).toContain('FROM node:20-alpine AS builder')
      expect(content).toContain('FROM node:20-alpine')
      expect(content.match(/FROM node:20-alpine/g)!.length).toBe(2)
    })
  })

  describe('Environment Configuration', () => {
    it('should have .env.production file', () => {
      const envPath = path.join(process.cwd(), '.env.production')
      expect(fs.existsSync(envPath)).toBe(true)
    })

    it('should have .env.test file', () => {
      const envPath = path.join(process.cwd(), '.env.test')
      expect(fs.existsSync(envPath)).toBe(true)
    })

    it('should have production API URL configured', () => {
      const envPath = path.join(process.cwd(), '.env.production')
      const content = fs.readFileSync(envPath, 'utf-8')
      expect(content).toContain('NEXT_PUBLIC_API_URL')
      expect(content).toContain('NODE_ENV=production')
    })

    it('should not expose sensitive data in .env files', () => {
      const envPath = path.join(process.cwd(), '.env.production')
      const content = fs.readFileSync(envPath, 'utf-8')
      expect(content).not.toContain('SECRET')
      expect(content).not.toContain('PRIVATE_KEY')
      expect(content).not.toContain('PASSWORD')
    })
  })

  describe('CI/CD Workflows', () => {
    it('should have test and validate workflow', () => {
      const workflowPath = path.join(process.cwd(), '.gitea/workflows/test-and-validate.yml')
      expect(fs.existsSync(workflowPath)).toBe(true)
    })

    it('should have production deployment workflow', () => {
      const workflowPath = path.join(process.cwd(), '.gitea/workflows/deploy-prod.yml')
      expect(fs.existsSync(workflowPath)).toBe(true)
    })

    it('test workflow should run tests', () => {
      const workflowPath = path.join(process.cwd(), '.gitea/workflows/test-and-validate.yml')
      const content = fs.readFileSync(workflowPath, 'utf-8')
      expect(content).toContain('npm run test:ci')
      expect(content).toContain('npm run build')
    })

    it('test workflow should check coverage', () => {
      const workflowPath = path.join(process.cwd(), '.gitea/workflows/test-and-validate.yml')
      const content = fs.readFileSync(workflowPath, 'utf-8')
      expect(content).toContain('coverage')
      expect(content).toContain('90')
    })

    it('production workflow should deploy with kubectl', () => {
      const workflowPath = path.join(process.cwd(), '.gitea/workflows/deploy-prod.yml')
      const content = fs.readFileSync(workflowPath, 'utf-8')
      expect(content).toContain('kubectl')
      expect(content).toContain('Deploy to Production')
    })
  })

  describe('Build Configuration', () => {
    it('should have next.config.js', () => {
      const nextConfigPath = path.join(process.cwd(), 'next.config.js')
      expect(fs.existsSync(nextConfigPath)).toBe(true)
    })

    it('should have tsconfig.json', () => {
      const tsconfigPath = path.join(process.cwd(), 'tsconfig.json')
      expect(fs.existsSync(tsconfigPath)).toBe(true)
    })

    it('should have jest.config.js', () => {
      const jestConfigPath = path.join(process.cwd(), 'jest.config.js')
      expect(fs.existsSync(jestConfigPath)).toBe(true)
    })

    it('should have package.json with build script', () => {
      const packageJsonPath = path.join(process.cwd(), 'package.json')
      const content = fs.readFileSync(packageJsonPath, 'utf-8')
      const packageJson = JSON.parse(content)
      expect(packageJson.scripts).toHaveProperty('build')
      expect(packageJson.scripts.build).toContain('next build')
    })
  })

  describe('Documentation', () => {
    it('should have deployment guide', () => {
      const docPath = path.join(process.cwd(), 'docs/DEPLOYMENT.md')
      expect(fs.existsSync(docPath)).toBe(true)
    })

    it('should have README.md', () => {
      const readmePath = path.join(process.cwd(), 'README.md')
      expect(fs.existsSync(readmePath)).toBe(true)
    })

    it('deployment guide should include troubleshooting', () => {
      const docPath = path.join(process.cwd(), 'docs/DEPLOYMENT.md')
      const content = fs.readFileSync(docPath, 'utf-8')
      expect(content).toContain('Troubleshooting')
      expect(content).toContain('Health Check')
    })
  })

  describe('Security Configuration', () => {
    it('should have .dockerignore file', () => {
      const dockerignorePath = path.join(process.cwd(), '.dockerignore')
      expect(fs.existsSync(dockerignorePath)).toBe(true)
    })

    it('.dockerignore should exclude node_modules', () => {
      const dockerignorePath = path.join(process.cwd(), '.dockerignore')
      const content = fs.readFileSync(dockerignorePath, 'utf-8')
      expect(content).toContain('node_modules')
    })

    it('should have .gitignore file', () => {
      const gitignorePath = path.join(process.cwd(), '.gitignore')
      expect(fs.existsSync(gitignorePath)).toBe(true)
    })

    it('.gitignore should exclude .env files', () => {
      const gitignorePath = path.join(process.cwd(), '.gitignore')
      const content = fs.readFileSync(gitignorePath, 'utf-8')
      expect(content).toContain('.env')
    })
  })

  describe('Build Optimization', () => {
    it('package.json should have build optimization scripts', () => {
      const packageJsonPath = path.join(process.cwd(), 'package.json')
      const content = fs.readFileSync(packageJsonPath, 'utf-8')
      const packageJson = JSON.parse(content)
      expect(packageJson.scripts).toHaveProperty('build')
      expect(packageJson.scripts).toHaveProperty('start')
      expect(packageJson.scripts).toHaveProperty('dev')
    })

    it('should have proper npm dependencies', () => {
      const packageJsonPath = path.join(process.cwd(), 'package.json')
      const content = fs.readFileSync(packageJsonPath, 'utf-8')
      const packageJson = JSON.parse(content)

      // Production dependencies
      expect(packageJson.dependencies).toHaveProperty('next')
      expect(packageJson.dependencies).toHaveProperty('react')
      expect(packageJson.dependencies).toHaveProperty('react-dom')

      // Dev dependencies
      expect(packageJson.devDependencies).toHaveProperty('typescript')
      expect(packageJson.devDependencies).toHaveProperty('jest')
    })
  })

  describe('Kubernetes Configuration', () => {
    it('should have k3s deployment manifests', () => {
      const k3sDir = path.join(process.cwd(), 'deploy/k3s/prod')
      expect(fs.existsSync(k3sDir)).toBe(true)
    })

    it('should have kustomization.yaml', () => {
      const kustomizePath = path.join(process.cwd(), 'deploy/k3s/prod/kustomization.yaml')
      expect(fs.existsSync(kustomizePath)).toBe(true)
    })
  })
})
