/**
 * WebDAV XML response builders.
 * Generates DAV-compliant XML without external dependencies.
 */

export interface DavResource {
  href: string
  isCollection: boolean
  displayName: string
  contentType?: string
  contentLength?: number
  lastModified?: Date
  createdAt?: Date
  etag?: string
}

function escapeXml(str: string): string {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
}

function formatRfc1123(date: Date): string {
  return date.toUTCString()
}

function formatIso8601(date: Date): string {
  return date.toISOString()
}

function buildResourceResponse(resource: DavResource): string {
  const props: string[] = []

  if (resource.isCollection) {
    props.push('<D:resourcetype><D:collection/></D:resourcetype>')
  } else {
    props.push('<D:resourcetype/>')
  }

  props.push(`<D:displayname>${escapeXml(resource.displayName)}</D:displayname>`)

  if (resource.contentType && !resource.isCollection) {
    props.push(`<D:getcontenttype>${escapeXml(resource.contentType)}</D:getcontenttype>`)
  }

  if (resource.contentLength != null && !resource.isCollection) {
    props.push(`<D:getcontentlength>${resource.contentLength}</D:getcontentlength>`)
  }

  if (resource.lastModified) {
    props.push(`<D:getlastmodified>${formatRfc1123(resource.lastModified)}</D:getlastmodified>`)
  }

  if (resource.createdAt) {
    props.push(`<D:creationdate>${formatIso8601(resource.createdAt)}</D:creationdate>`)
  }

  if (resource.etag) {
    props.push(`<D:getetag>"${escapeXml(resource.etag)}"</D:getetag>`)
  }

  return `<D:response>
<D:href>${escapeXml(resource.href)}</D:href>
<D:propstat>
<D:prop>
${props.join('\n')}
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>`
}

export function buildMultistatus(resources: DavResource[]): string {
  const responses = resources.map(buildResourceResponse).join('\n')
  return `<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:">
${responses}
</D:multistatus>`
}

export function buildLockResponse(lockToken: string, owner: string, timeout: number): string {
  return `<?xml version="1.0" encoding="utf-8"?>
<D:prop xmlns:D="DAV:">
<D:lockdiscovery>
<D:activelock>
<D:locktype><D:write/></D:locktype>
<D:lockscope><D:exclusive/></D:lockscope>
<D:depth>infinity</D:depth>
<D:owner><D:href>${escapeXml(owner)}</D:href></D:owner>
<D:timeout>Second-${timeout}</D:timeout>
<D:locktoken><D:href>${escapeXml(lockToken)}</D:href></D:locktoken>
</D:activelock>
</D:lockdiscovery>
</D:prop>`
}

export function buildErrorResponse(statusCode: number, message: string): string {
  return `<?xml version="1.0" encoding="utf-8"?>
<D:error xmlns:D="DAV:">
<D:message>${escapeXml(message)}</D:message>
</D:error>`
}
