package org.apache.maven.plugin.failsafe.util;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.maven.surefire.shared.io.IOUtils;
import org.apache.maven.surefire.api.suite.RunResult;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;

import static java.lang.Boolean.parseBoolean;
import static java.lang.Integer.parseInt;
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.maven.surefire.shared.lang3.StringEscapeUtils.escapeXml10;
import static org.apache.maven.surefire.shared.lang3.StringEscapeUtils.unescapeXml;
import static org.apache.maven.surefire.shared.utils.StringUtils.isBlank;

/**
 * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
 * @since 2.20
 */
public final class FailsafeSummaryXmlUtils
{
    private static final String FAILSAFE_SUMMARY_XML_SCHEMA_LOCATION =
            "https://maven.apache.org/surefire/maven-surefire-plugin/xsd/failsafe-summary.xsd";

    private static final String MESSAGE_NIL_ELEMENT =
            "<failureMessage xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>";

    private static final String MESSAGE_ELEMENT =
            "<failureMessage>%s</failureMessage>";

    private static final String FAILSAFE_SUMMARY_XML_TEMPLATE =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
                    + "<failsafe-summary xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
                    + " xsi:noNamespaceSchemaLocation=\"" + FAILSAFE_SUMMARY_XML_SCHEMA_LOCATION + "\""
                    + " result=\"%s\" timeout=\"%s\">\n"
                    + "    <completed>%d</completed>\n"
                    + "    <errors>%d</errors>\n"
                    + "    <failures>%d</failures>\n"
                    + "    <skipped>%d</skipped>\n"
                    + "    %s\n"
                    + "</failsafe-summary>";

    private FailsafeSummaryXmlUtils()
    {
        throw new IllegalStateException( "No instantiable constructor." );
    }

    public static RunResult toRunResult( File failsafeSummaryXml ) throws Exception
    {
        XPathFactory xpathFactory = XPathFactory.newInstance();
        XPath xpath = xpathFactory.newXPath();

        try ( FileInputStream is = new FileInputStream( failsafeSummaryXml ) )
        {
            Node root = ( Node ) xpath.evaluate( "/", new InputSource( is ), XPathConstants.NODE );

            String completed = xpath.evaluate( "/failsafe-summary/completed", root );
            String errors = xpath.evaluate( "/failsafe-summary/errors", root );
            String failures = xpath.evaluate( "/failsafe-summary/failures", root );
            String skipped = xpath.evaluate( "/failsafe-summary/skipped", root );
            String failureMessage = xpath.evaluate( "/failsafe-summary/failureMessage", root );
            String timeout = xpath.evaluate( "/failsafe-summary/@timeout", root );

            return new RunResult( parseInt( completed ), parseInt( errors ), parseInt( failures ), parseInt( skipped ),
                    isBlank( failureMessage ) ? null : unescapeXml( failureMessage ),
                    parseBoolean( timeout )
            );
        }
    }

    public static void fromRunResultToFile( RunResult fromRunResult, File toFailsafeSummaryXml )
            throws IOException
    {
        String failure = fromRunResult.getFailure();
        String msg = isBlank( failure ) ? MESSAGE_NIL_ELEMENT : format( MESSAGE_ELEMENT, escapeXml10( failure ) );
        String xml = format( Locale.ROOT, FAILSAFE_SUMMARY_XML_TEMPLATE,
                fromRunResult.getFailsafeCode(),
                String.valueOf( fromRunResult.isTimeout() ),
                fromRunResult.getCompletedCount(),
                fromRunResult.getErrors(),
                fromRunResult.getFailures(),
                fromRunResult.getSkipped(),
                msg );

        try ( FileOutputStream os = new FileOutputStream( toFailsafeSummaryXml ) )
        {
            IOUtils.write( xml, os, UTF_8 );
        }
    }

    public static void writeSummary( RunResult mergedSummary, File mergedSummaryFile, boolean inProgress )
            throws Exception
    {
        if ( !mergedSummaryFile.getParentFile().isDirectory() )
        {
            //noinspection ResultOfMethodCallIgnored
            mergedSummaryFile.getParentFile().mkdirs();
        }

        if ( mergedSummaryFile.exists() && inProgress )
        {
            RunResult runResult = toRunResult( mergedSummaryFile );
            mergedSummary = mergedSummary.aggregate( runResult );
        }

        fromRunResultToFile( mergedSummary, mergedSummaryFile );
    }
}
