name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
    tags: [ 'v*' ]
  pull_request:
    branches: [ main, develop ]

env:
  POSTGRES_DB: platform_test
  POSTGRES_USER: platform_user
  POSTGRES_PASSWORD: test_password
  DATABASE_URL: "postgresql://platform_user:test_password@localhost:5432/platform_test"
  REDIS_URL: "redis://localhost:6379/0"

jobs:
  # Backend тесты
  test-backend:
    runs-on: ubuntu-latest
    
    services:
      postgres:
        image: postgres:16-alpine
        env:
          POSTGRES_DB: ${{ env.POSTGRES_DB }}
          POSTGRES_USER: ${{ env.POSTGRES_USER }}
          POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }}
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
      
      redis:
        image: redis:7-alpine
        ports:
          - 6379:6379
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Set up Python 3.11
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
          cache: 'pip'
      
      - name: Install dependencies
        working-directory: ./backend
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      
      - name: Run Django checks
        working-directory: ./backend
        env:
          DJANGO_SETTINGS_MODULE: config.settings
          SECRET_KEY: test-secret-key-for-ci
          DEBUG: False
          ALLOWED_HOSTS: "*"
        run: python manage.py check
      
      - name: Run tests with coverage
        working-directory: ./backend
        env:
          DJANGO_SETTINGS_MODULE: config.settings
          SECRET_KEY: test-secret-key-for-ci
          DEBUG: False
          ALLOWED_HOSTS: "*"
        run: |
          pytest --cov=apps --cov-report=xml --cov-report=html --cov-report=term-missing
      
      - name: Upload coverage reports
        uses: codecov/codecov-action@v3
        with:
          file: ./backend/coverage.xml
          flags: backend
          name: backend-coverage
  
  # Backend linting
  lint-backend:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Set up Python 3.11
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      
      - name: Install linting tools
        run: pip install flake8 black isort
      
      - name: Run flake8
        working-directory: ./backend
        run: flake8 apps config --max-line-length=120 --exclude=migrations,__pycache__
      
      - name: Run black
        working-directory: ./backend
        run: black --check apps config --exclude migrations
      
      - name: Run isort
        working-directory: ./backend
        run: isort --check-only apps config --skip migrations
  
  # Frontend тесты
  test-frontend:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Set up Node.js 18
        uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'npm'
          cache-dependency-path: frontend/package-lock.json
      
      - name: Install dependencies
        working-directory: ./frontend
        run: npm ci
      
      - name: Run linting
        working-directory: ./frontend
        run: npm run lint
      
      - name: Run type checking
        working-directory: ./frontend
        run: npm run type-check || true
      
      - name: Build
        working-directory: ./frontend
        run: npm run build
  
  # Security проверки
  security-backend:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Set up Python 3.11
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      
      - name: Install security tools
        run: pip install safety bandit
      
      - name: Run safety check
        working-directory: ./backend
        run: safety check --json || true
      
      - name: Run bandit
        working-directory: ./backend
        run: bandit -r apps config -ll || true
  
  # Сборка Docker образов
  build:
    needs: [test-backend, test-frontend, lint-backend]
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/tags/v'))
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      
      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: |
            ${{ secrets.DOCKER_USERNAME }}/platform-backend
            ${{ secrets.DOCKER_USERNAME }}/platform-frontend
      
      - name: Build and push Backend image
        uses: docker/build-push-action@v5
        with:
          context: ./backend
          push: true
          tags: ${{ secrets.DOCKER_USERNAME }}/platform-backend:${{ github.ref_name }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
      
      - name: Build and push Frontend image
        uses: docker/build-push-action@v5
        with:
          context: ./frontend
          push: true
          tags: ${{ secrets.DOCKER_USERNAME }}/platform-frontend:${{ github.ref_name }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
  
  # Deploy на Staging
  deploy-staging:
    needs: [build]
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/develop'
    environment:
      name: staging
      url: https://staging.platform.example.com
    
    steps:
      - name: Deploy to Staging
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.STAGING_HOST }}
          username: ${{ secrets.STAGING_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /opt/platform
            docker compose pull
            docker compose up -d
  
  # Deploy на Production
  deploy-production:
    needs: [build]
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
    environment:
      name: production
      url: https://platform.example.com
    
    steps:
      - name: Deploy to Production
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.PRODUCTION_HOST }}
          username: ${{ secrets.PRODUCTION_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /opt/platform
            docker compose pull
            docker compose up -d
            
      - name: Notify deployment
        if: always()
        run: echo "Deployment completed with status ${{ job.status }}"

