# All Rights Reserved.
#
#    Licensed 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 datetime as dt
import itertools
import os

from rally.common.io import junit
from rally.task import exporter


@exporter.configure("junit-xml")
class JUnitXMLExporter(exporter.TaskExporter):
    """Generates task report in JUnit-XML format.

    An example of the report (All dates, numbers, names appearing in this
    example are fictitious. Any resemblance to real things is purely
    coincidental):

    .. code-block:: xml

      <testsuites>
        <!--Report is generated by Rally 0.10.0 at 2017-06-04T05:14:00-->
        <testsuite id="task-uu-ii-dd"
                   errors="0"
                   failures="1"
                   skipped="0"
                   tests="2"
                   time="75.0"
                   timestamp="2017-06-04T05:14:00">
          <testcase classname="CinderVolumes"
                    name="list_volumes"
                    id="workload-1-uuid"
                    time="29.9695231915"
                    timestamp="2017-06-04T05:14:44" />
          <testcase classname="NovaServers"
                    name="list_keypairs"
                    id="workload-2-uuid"
                    time="5"
                    timestamp="2017-06-04T05:15:15">
            <failure>ooops</failure>
          </testcase>
        </testsuite>
      </testsuites>
    """

    def generate(self):
        root = junit.JUnitXML()

        for t in self.tasks_results:
            created_at = dt.datetime.strptime(
                t["created_at"], "%Y-%m-%dT%H:%M:%S"
            )
            updated_at = dt.datetime.strptime(
                t["updated_at"], "%Y-%m-%dT%H:%M:%S"
            )
            test_suite = root.add_test_suite(
                id=t["uuid"],
                time="%.2f" % (updated_at - created_at).total_seconds(),
                timestamp=t["created_at"],
            )
            for workload in itertools.chain(
                *[s["workloads"] for s in t["subtasks"]]
            ):
                class_name, name = workload["name"].split(".", 1)
                test_case = test_suite.add_test_case(
                    id=workload["uuid"],
                    time="%.2f" % workload["full_duration"],
                    classname=class_name,
                    name=name,
                    timestamp=workload["created_at"],
                )
                if not workload["pass_sla"]:
                    details = "\n".join(
                        [
                            s["detail"]
                            for s in workload["sla_results"]["sla"]
                            if not s["success"]
                        ]
                    )
                    test_case.mark_as_failed(details)

        raw_report = root.to_string()

        if self.output_destination:
            return {
                "files": {self.output_destination: raw_report},
                "open": "file://" + os.path.abspath(self.output_destination),
            }
        else:
            return {"print": raw_report}
