/*
    StrataSignature.cpp

    Copyright (C) 2009  RedHat inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "abrtlib.h"
#include "abrt_xmlrpc.h" /* for xcurl_easy_init */
#include "StrataSignature.h"
#include "DebugDump.h"
#include "ABRTException.h"
#include "CommLayerInner.h"

#include "strata_client.h"

using namespace std;


CStrataSignature::CStrataSignature()
{}

CStrataSignature::~CStrataSignature()
{}

string CStrataSignature::Report(const map_crash_data_t& pCrashData,
                const map_plugin_settings_t& pSettings,
                const char *pArgs)
{
    string URL;

    map_plugin_settings_t settings = parse_settings(pSettings);
    if (!settings.empty())
    {
        URL = settings["URL"];
    }
    else
    {
        URL = m_sURL;
    }
    update_client(_("Creating a signature..."));

    reportfile_t* file = reportfile_start(1);
    if (!file)
    {
	throw CABRTException(EXCEP_PLUGIN, "%s", strata_client_strerror());
    }

    // Copy each entry into the tarball root.
    // Files are simply copied, strings are written to a file
    // TODO: some files are totally useless:
    // "Reported", "Message" (plugin's output), "DumpDir",
    // "Description" (package description) - maybe skip those?
    int rc;
    map_crash_data_t::const_iterator it;
    for (it = pCrashData.begin(); it != pCrashData.end(); it++)
    {
        const char *content = it->second[CD_CONTENT].c_str();
        if (it->second[CD_TYPE] == CD_TXT)
	{
	  rc = reportfile_add_binding_from_string(file, 
						  it->first.c_str(), 
						  content, 0, 0);
	    if (rc < 0) 
	    {
		throw CABRTException(EXCEP_PLUGIN, "%s", strata_client_strerror());
	    }
        }
        else if (it->second[CD_TYPE] == CD_BIN)
        {
	    rc = reportfile_add_binding_from_namedfile(file, 
						       it->first.c_str(),
						       content, 1, content);
	    if (rc < 0) 
	    {
		throw CABRTException(EXCEP_PLUGIN, "%s", strata_client_strerror());
	    } 
        }
    }

    rc = reportfile_end(file);
    if (rc < 0) 
    {
	throw CABRTException(EXCEP_PLUGIN, "%s", strata_client_strerror());
    } 
    
    char* signature = reportfile_as_string(file);
    if (!signature) 
    {
	throw CABRTException(EXCEP_PLUGIN, "%s", strata_client_strerror());
    } 
  
    rc = reportfile_free(file);
    if (rc < 0)
    {
	throw CABRTException(EXCEP_PLUGIN, "%s", strata_client_strerror());
    } 

    update_client(_("Creating a signature..."));
    const char* p = post_signature(URL.c_str(), signature);
    if (!p)
    {
	throw CABRTException(EXCEP_PLUGIN, "%s", strata_client_strerror());
    }

    string msg = p;
    free((void*)p);
    return msg;
}

void CStrataSignature::SetSettings(const map_plugin_settings_t& pSettings)
{
  log("entering CStrataSignature::SetSettings");
    m_pSettings = pSettings;

    map_plugin_settings_t::const_iterator end = pSettings.end();
    map_plugin_settings_t::const_iterator it;
    it = pSettings.find("URL");
    if (it != end)
    {
        m_sURL = it->second;
    }
}

const map_plugin_settings_t& CStrataSignature::GetSettings()
{
    m_pSettings["URL"] = m_sURL;
    return m_pSettings;
}

//todo: make static
map_plugin_settings_t CStrataSignature::parse_settings(const map_plugin_settings_t& pSettings)
{
    map_plugin_settings_t plugin_settings;

    map_plugin_settings_t::const_iterator end = pSettings.end();
    map_plugin_settings_t::const_iterator it;

    it = pSettings.find("URL");
    if (it == end)
    {
        plugin_settings.clear();
        return plugin_settings;
    }
    plugin_settings["URL"] = it->second;
    VERB1 log("User settings ok, using them instead of defaults");
    return plugin_settings;
}

PLUGIN_INFO(REPORTER,
            CStrataSignature,
            "StrataSignature",
            "0.0.1",
            "Sends a signature to a Strata signature service.",
            "gavin@redhat.com",
            "https://fedorahosted.org/abrt/wiki",
            PLUGINS_LIB_DIR"/StrataSignature.GTKBuilder");