/**
* @file lltranslate.h
* @brief Human language translation class and JSON response receiver.
*
 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_LLTRANSLATE_H
#define LL_LLTRANSLATE_H

#include "llbufferstream.h"
#include <boost/function.hpp>

#include "llsingleton.h"

namespace Json
{
    class Value;
}

class LLTranslationAPIHandler;
/**
 * Entry point for machine translation services.
 *
 * Basically, to translate a string, we need to know the URL
 * of a translation service, have a valid API for the service
 * and be given the target language.
 *
 * Callers specify the string to translate and the target language,
 * LLTranslate takes care of the rest.
 *
 * API keys for translation are taken from saved settings.
 */
class LLTranslate: public LLSingleton<LLTranslate>
{
	LLSINGLETON(LLTranslate);
	~LLTranslate();
	LOG_CLASS(LLTranslate);

public :

	typedef enum e_service {
		SERVICE_AZURE,
		SERVICE_GOOGLE,
		SERVICE_DEEPL,
	} EService;

    typedef boost::function<void(EService, bool, S32)> KeyVerificationResult_fn;
    typedef boost::function<void(std::string , std::string )> TranslationSuccess_fn;
    typedef boost::function<void(int, std::string)> TranslationFailure_fn;

	/**
	 * Translate given text.
	 *
	 * @param receiver   Object to pass translation result to.
	 * @param from_lang  Source language. Leave empty for auto-detection.
	 * @param to_lang    Target language.
	 * @param mesg       Text to translate.
	 */
    static void translateMessage(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, TranslationSuccess_fn success, TranslationFailure_fn failure);

    /**
     * Verify given API key of a translation service.
     *
     * @param receiver  Object to pass verification result to.
     * @param key       Key to verify.
     */
    static void verifyKey(EService service, const LLSD &key, KeyVerificationResult_fn fnc);

	/**
	 * @return translation target language
	 */
	static std::string getTranslateLanguage();

	/**
	 * @return true if translation is configured properly.
	 */
	static bool isTranslationConfigured();

    static std::string addNoTranslateTags(std::string mesg);
    static std::string removeNoTranslateTags(std::string mesg);

	void logCharsSeen(size_t count);
	void logCharsSent(size_t count);
	void logSuccess(S32 count);
	void logFailure(S32 count);
	LLSD asLLSD() const;
private:
	static LLTranslationAPIHandler& getPreferredHandler();
	static LLTranslationAPIHandler& getHandler(EService service);

	size_t mCharsSeen;
	size_t mCharsSent;
	S32 mFailureCount;
	S32 mSuccessCount;
};

#endif