namespace std { class type_info; }

#include <reporter.hh>
#include <file-parser.hh>
#include <configuration.hh>
#include <writer.hh>
#include <utils.hh>

#include <string>
#include <list>
#include <unordered_map>
#include <iostream>
#include <fstream>

#include "writer-base.hh"
#include "sonarqube-xml-writer.hh"

using namespace kcov;

class SonarQubeWriter : public WriterBase
{
public:
	SonarQubeWriter(IFileParser &parser, IReporter &reporter,
			const std::string &outFile) :
		WriterBase(parser, reporter),
		m_outFile(outFile),
		m_maxPossibleHits(parser.maxPossibleHits())
	{
	}

	void onStartup()
	{
	}

	void onStop()
	{
	}

	void write()
	{
		std::ofstream out(m_outFile);

		// Output directory not writable?
		if (!out.is_open())
			return;

		setupCommonPaths();

		out << "<!-- Generated by kcov (https://simonkagstrom.github.io/kcov/) -->\n";
		out << "<coverage version=\"1\">\n";

		for (FileMap_t::const_iterator it = m_files.begin();
				it != m_files.end();
				++it) {
			File *file = it->second;

			writeOne(file, out);
		}

		out << "</coverage>\n";
	}

private:
	void writeOne(File *file, std::ofstream &out)
	{
		out << fmt("	<file path=\"%s\">\n", file->m_name.c_str());

		for (unsigned int n = 1; n < file->m_lastLineNr; n++)
		{
			if (!m_reporter.lineIsCode(file->m_name, n))
					continue;

			IReporter::LineExecutionCount cnt =
					m_reporter.getLineExecutionCount(file->m_name, n);

			std::string covered = cnt.m_hits ? "true" : "false";

			out << fmt("		<lineToCover lineNumber=\"%d\" covered=\"%s\"/>\n", n, covered.c_str());
		}

		out << "	</file>\n";
	}

	std::string getHeader(unsigned int nCodeLines, unsigned int nExecutedLines)
	{
		return "<?xml version=\"1.0\" ?>\n";
	}

	const std::string getFooter()
	{
		return "";
	}


	std::string m_outFile;
	IFileParser::PossibleHits m_maxPossibleHits;
};

namespace kcov
{
	IWriter &createSonarqubeWriter(IFileParser &parser, IReporter &reporter,
			const std::string &outFile)
	{
		return *new SonarQubeWriter(parser, reporter, outFile);
	}
}
