import Foundation

/// Reports violations as JUnit XML.
struct JUnitReporter: Reporter {
    // MARK: - Reporter Conformance

    static let identifier = "junit"
    static let isRealtime = false
    static let description = "Reports violations as JUnit XML."

    static func generateReport(_ violations: [StyleViolation]) -> String {
        let warningCount = violations.filter({ $0.severity == .warning }).count
        let errorCount = violations.filter({ $0.severity == .error }).count
        let testCount = warningCount + errorCount

        return """
            <?xml version="1.0" encoding="utf-8"?>
            <testsuites name="SwiftLint" failures="\(warningCount)" errors="\(errorCount)" tests="\(testCount)">
            \t<testsuite name="SwiftLint" failures="\(warningCount)" errors="\(errorCount)" tests="\(testCount)">
            \(violations.map(testCase(for:)).joined(separator: "\n"))
            \t</testsuite>
            </testsuites>
            """
    }

    private static func testCase(for violation: StyleViolation) -> String {
        let fileName = (violation.location.file?.path ?? "<nopath>").escapedForXML()
        let reason = violation.reason.escapedForXML()
        let severity = violation.severity.rawValue.capitalized
        let lineNumber = String(violation.location.line ?? 0)
        let message = severity + ":" + "Line:" + lineNumber

        return """
            \t\t<testcase classname='Formatting Test' name='\(fileName)'>
            \t\t\t<failure message='\(reason)'>\(message)</failure>
            \t\t</testcase>
            """
    }
}
