#include "xml_checker.h"

#include <library/cpp/xml/sax/sax.h>
#include <util/string/vector.h>

namespace {
    class TXmlValidatorCallback: public NXml::ISaxHandler {
    private:
        inline TString GetErrorString(const TErrorInfo& ei) {
            return "line:" + ToString(ei.Line) + " column:" + ToString(ei.Column) + " " +
                    ei.Context + ": " + ei.Message;
        }
        TVector<TString> Errors;
    public:
        // stubs
        void OnStartElement(const char* /*name*/, const char** /*attrs*/) override {}
        void OnEndElement(const char* /*name*/) override {}
        void OnText(const char* /*text*/, size_t /*len*/) override {}
        void OnWarning(const TErrorInfo& /*ei*/) override {}

        void OnError(const TErrorInfo& ei) override {
            Errors.push_back("Error: " + GetErrorString(ei));
        }

        void OnFatalError(const TErrorInfo& ei) override {
            Errors.push_back("Fatal error: " + GetErrorString(ei));
        }

        inline const TVector<TString>& GetErrors() const {
            return Errors;
        }
    };
}

bool CheckXml(const TString& body, TString& errors) {
    if (!body)
        return true;
    TStringInput ss(body);
    TXmlValidatorCallback cb;
    NXml::ParseXml(&ss, &cb);
    errors = JoinStrings(cb.GetErrors(), "\n");
    return cb.GetErrors().empty();
}
