import type { DifyWorld } from '../../../support/world'
import { failFixturePrerequisite } from './common'

const isTruthyEnv = (value: string | undefined) => value === '1' || value === 'true'

const getDefaultAgentBackendURL = () => {
  const port = process.env.E2E_AGENT_BACKEND_PORT?.trim() || '5050'

  return `http://127.0.0.1:${port}`
}

const getShellctlURL = () => {
  const explicitE2EURL = process.env.E2E_SHELLCTL_URL?.trim()
  if (explicitE2EURL) return explicitE2EURL.replace(/\/$/, '')

  const explicitAgentURL = process.env.DIFY_AGENT_SHELLCTL_ENTRYPOINT?.trim()
  if (explicitAgentURL) return explicitAgentURL.replace(/\/$/, '')

  if (isTruthyEnv(process.env.E2E_START_AGENT_BACKEND)) {
    const port = process.env.E2E_SHELLCTL_PORT?.trim() || '5004'
    return `http://127.0.0.1:${port}`
  }

  return undefined
}

const getAgentBackendURL = () => {
  const explicitE2EURL = process.env.E2E_AGENT_BACKEND_URL?.trim()
  if (explicitE2EURL) return explicitE2EURL.replace(/\/$/, '')

  const explicitAPIURL = process.env.AGENT_BACKEND_BASE_URL?.trim()
  if (explicitAPIURL) return explicitAPIURL.replace(/\/$/, '')

  if (isTruthyEnv(process.env.E2E_START_AGENT_BACKEND)) return getDefaultAgentBackendURL()

  return undefined
}

const checkRuntimeEndpoint = async ({
  path,
  remediation,
  title,
  url,
  world,
}: {
  path: string
  remediation: string
  title: string
  url: string
  world: DifyWorld
}) => {
  const healthURL = `${url}${path}`
  try {
    const response = await fetch(healthURL)
    if (response.ok) return undefined

    return failFixturePrerequisite(
      world,
      `${title} did not respond successfully at ${healthURL}: ${response.status} ${response.statusText}.`,
      {
        owner: 'e2e/runtime',
        remediation,
      },
    )
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error)

    return failFixturePrerequisite(world, `${title} is unreachable at ${healthURL}: ${message}.`, {
      owner: 'e2e/runtime',
      remediation,
    })
  }
}

export async function requireAgentBackendRuntime(world: DifyWorld) {
  const agentBackendURL = getAgentBackendURL()

  if (!agentBackendURL) {
    return failFixturePrerequisite(
      world,
      'Agent v2 runtime backend is not configured. This scenario needs the standalone dify-agent run server, not just an active model provider.',
      {
        owner: 'e2e/runtime',
        remediation:
          'Run with E2E_START_AGENT_BACKEND=1 to let E2E start dify-agent, or set E2E_AGENT_BACKEND_URL/AGENT_BACKEND_BASE_URL to an existing dify-agent server.',
      },
    )
  }

  const agentBackendBlock = await checkRuntimeEndpoint({
    path: '/openapi.json',
    remediation:
      'Start a healthy dify-agent server and make sure AGENT_BACKEND_BASE_URL points to it before running Agent v2 runtime scenarios.',
    title: 'Agent v2 runtime backend',
    url: agentBackendURL,
    world,
  })
  if (agentBackendBlock) return agentBackendBlock

  const shellctlURL = getShellctlURL()
  if (shellctlURL) {
    const shellctlBlock = await checkRuntimeEndpoint({
      path: '/healthz',
      remediation:
        'Start the shellctl local sandbox, or run with E2E_START_AGENT_BACKEND=1 so E2E starts it together with dify-agent.',
      title: 'Agent v2 shellctl sandbox',
      url: shellctlURL,
      world,
    })
    if (shellctlBlock) return shellctlBlock
  }

  return agentBackendURL
}
