import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'

import { describe, expect, it } from 'vitest'

import {
  renderNginxConfig,
  renderSystemdService,
  resolveDeploymentRenderOptions,
  writeRenderedDeploymentFiles,
} from './render-same-origin-deployment-lib.mjs'

describe('resolveDeploymentRenderOptions', () => {
  it('derives website/server paths from the checkout root by default', () => {
    const options = resolveDeploymentRenderOptions({
      checkoutRoot: '/srv/hypertwist/current',
    })

    expect(options.websiteRoot).toBe('/srv/hypertwist/current/website')
    expect(options.serverRoot).toBe('/srv/hypertwist/current/website/server')
    expect(options.environmentFile).toBe('/srv/hypertwist/current/website/server/.env')
    expect(options.serverNames).toEqual(['hypertwist.app', 'www.hypertwist.app'])
  })
})

describe('renderSystemdService', () => {
  it('renders a production systemd unit with the resolved checkout paths', () => {
    const rendered = renderSystemdService({
      checkoutRoot: '/srv/hypertwist/current',
      serviceUser: 'deploy',
      serviceGroup: 'www-data',
      environmentFile: '/etc/hypertwist/server.env',
    })

    expect(rendered).toContain('User=deploy')
    expect(rendered).toContain('Group=www-data')
    expect(rendered).toContain('WorkingDirectory=/srv/hypertwist/current/website/server')
    expect(rendered).toContain('EnvironmentFile=/etc/hypertwist/server.env')
    expect(rendered).toContain('ExecStart=/usr/bin/npm start')
  })
})

describe('renderNginxConfig', () => {
  it('renders a same-origin nginx vhost for the configured hostnames and port', () => {
    const rendered = renderNginxConfig({
      checkoutRoot: '/srv/hypertwist/current',
      serverNames: ['hypertwist.app', 'preview.hypertwist.app'],
      certificateName: 'hypertwist.app',
      upstreamPort: 4100,
      upstreamName: 'hypertwist_preview',
    })

    expect(rendered).toContain('server_name hypertwist.app preview.hypertwist.app;')
    expect(rendered).toContain('server 127.0.0.1:4100;')
    expect(rendered).toContain('ssl_certificate /etc/letsencrypt/live/hypertwist.app/fullchain.pem;')
    expect(rendered).toContain('proxy_pass http://hypertwist_preview;')
  })
})

describe('writeRenderedDeploymentFiles', () => {
  it('writes both rendered files to disk when output paths are provided', () => {
    const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'hypertwist-deploy-render-'))
    const systemdOut = path.join(tempDir, 'hypertwist.service')
    const nginxOut = path.join(tempDir, 'hypertwist.conf')

    try {
      writeRenderedDeploymentFiles({
        checkoutRoot: '/srv/hypertwist/current',
        systemdOut,
        nginxOut,
      })

      expect(fs.readFileSync(systemdOut, 'utf8')).toContain('WorkingDirectory=/srv/hypertwist/current/website/server')
      expect(fs.readFileSync(nginxOut, 'utf8')).toContain('server_name hypertwist.app www.hypertwist.app;')
    } finally {
      fs.rmSync(tempDir, { recursive: true, force: true })
    }
  })
})
