/*
 * BEGIN FLOCK GPL
 *
 * Copyright Flock Inc. 2005-2009
 * http://flock.com
 *
 * This file may be used under the terms of the
 * GNU General Public License Version 2 or later (the "GPL"),
 * http://www.gnu.org/licenses/gpl.html
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * END FLOCK GPL
 */

#include "nsIGenericFactory.h"

#include "flockRDFService.h"
#include "flockStreamUtils.h"
#include "flockSystemInfo.h"
#include "flockRDFSourceUtils.h"
//#include "flockPriorityQueue.h"
//#include "flockAggregator.h"
#include "flockTokenizer.h"
#include "flockCompressContent.h"
#include "flockLogger.h"
#include "flockLoggingWriters.h"
#include "flockFaviconDataService.h"
#include "flockAboutRedirector.h"

#include "nsICategoryManager.h"
#include "nsXPCOMCID.h"
#include "nsServiceManagerUtils.h"


#define FLOCK_RDF_SERVICE_CLASSNAME "Flock RDF Service"
#define FLOCK_RDF_SERVICE_CID { 0xae08f598, 0x5940, 0x4e8e, \
  { 0xab, 0xeb, 0xb8, 0x89, 0x0e, 0x1b, 0xa0, 0xa4 } }
//#define FLOCK_RDF_SERVICE_CONTRACTID "@mozilla.org/rdf/datasource;1?name=flock-rdf"
#define FLOCK_RDF_SERVICE_CONTRACTID "@mozilla.org/rdf/datasource;1?name=flock-favorites"


NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(flockRDFService,
    flockRDFService::GetSingleton)

static NS_METHOD
flockRDFServiceRegister(nsIComponentManager *aCompMgr,
                        nsIFile *aPath,
                        const char *registryLocation,
                        const char *componentType,
                        const nsModuleComponentInfo *info)
{
  nsresult rv;
  nsCOMPtr<nsICategoryManager> catmgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  return catmgr->AddCategoryEntry("app-startup", FLOCK_RDF_SERVICE_CLASSNAME,
      "service," FLOCK_RDF_SERVICE_CONTRACTID, PR_TRUE, PR_TRUE,
      nsnull);
}

static NS_METHOD
flockRDFServiceUnregister(nsIComponentManager *aCompMgr,
                          nsIFile *aPath,
                          const char *registryLocation,
                          const nsModuleComponentInfo *info)
{
  nsresult rv;
  nsCOMPtr<nsICategoryManager> catmgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = catmgr->DeleteCategoryEntry("app-startup",
      FLOCK_RDF_SERVICE_CLASSNAME, PR_TRUE);

  return rv;
}

NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(flockStreamCountsPropagator,
    flockStreamCountsPropagator::GetSingleton)

static NS_METHOD
flockStreamCountsPropagatorRegister(nsIComponentManager *aCompMgr,
                                    nsIFile *aPath,
                                    const char *registryLocation,
                                    const char *componentType,
                                    const nsModuleComponentInfo *info)
{
  nsresult rv;
  nsCOMPtr<nsICategoryManager> catmgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  return catmgr->AddCategoryEntry("flock-rdf-setup", FLOCK_STREAMCOUNTSPROPAGATOR_CLASSNAME,
      "service," FLOCK_STREAMCOUNTSPROPAGATOR_CONTRACTID, PR_TRUE, PR_TRUE,
      nsnull);
}

static NS_METHOD
flockStreamCountsPropagatorUnregister(nsIComponentManager *aCompMgr,
                                      nsIFile *aPath,
                                      const char *registryLocation,
                                      const nsModuleComponentInfo *info)
{
  nsresult rv;
  nsCOMPtr<nsICategoryManager> catmgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = catmgr->DeleteCategoryEntry("flock-rdf-setup",
      FLOCK_STREAMCOUNTSPROPAGATOR_CLASSNAME, PR_TRUE);

  return rv;
}

NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(flockLoggingService,
    flockLoggingService::GetSingleton)

static NS_METHOD
flockLoggingServiceRegister(nsIComponentManager *aCompMgr,
                            nsIFile *aPath,
                            const char *registryLocation,
                            const char *componentType,
                            const nsModuleComponentInfo *info)
{
  nsresult rv;
  nsCOMPtr<nsICategoryManager> catmgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  return catmgr->AddCategoryEntry("app-startup", FLOCK_LOGGINGSERVICE_CLASSNAME,
      "service," FLOCK_LOGGINGSERVICE_CONTRACTID, PR_TRUE, PR_TRUE,
      nsnull);
}

static NS_METHOD
flockLoggingServiceUnregister(nsIComponentManager *aCompMgr,
                              nsIFile *aPath,
                              const char *registryLocation,
                              const nsModuleComponentInfo *info)
{
  nsresult rv;
  nsCOMPtr<nsICategoryManager> catmgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = catmgr->DeleteCategoryEntry("app-startup",
      FLOCK_LOGGINGSERVICE_CLASSNAME, PR_TRUE);

  return rv;
}

NS_GENERIC_FACTORY_CONSTRUCTOR(flockLoggingConsoleWriter)

static NS_METHOD
flockLoggingConsoleWriterRegister(nsIComponentManager *aCompMgr,
                                  nsIFile *aPath,
                                  const char *registryLocation,
                                  const char *componentType,
                                  const nsModuleComponentInfo *info)
{
  nsresult rv;
  nsCOMPtr<nsICategoryManager> catmgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  return catmgr->AddCategoryEntry("flockILoggingObserver",
      FLOCK_LOGGINGCONSOLEWRITER_CLASSNAME,
      FLOCK_LOGGINGCONSOLEWRITER_CONTRACTID,
      PR_TRUE, PR_TRUE,
      nsnull);
}

static NS_METHOD
flockLoggingConsoleWriterUnregister(nsIComponentManager *aCompMgr,
                                    nsIFile *aPath,
                                    const char *registryLocation,
                                    const nsModuleComponentInfo *info)
{
  nsresult rv;
  nsCOMPtr<nsICategoryManager> catmgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = catmgr->DeleteCategoryEntry("flockILoggingObserver",
      FLOCK_LOGGINGCONSOLEWRITER_CLASSNAME, PR_TRUE);

  return rv;
}

NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(flockLoggingFileWriter, Init)

static NS_METHOD
flockLoggingFileWriterRegister(nsIComponentManager *aCompMgr,
                               nsIFile *aPath,
                               const char *registryLocation,
                               const char *componentType,
                               const nsModuleComponentInfo *info)
{
  nsresult rv;
  nsCOMPtr<nsICategoryManager> catmgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  return catmgr->AddCategoryEntry("flockILoggingObserver",
      FLOCK_LOGGINGFILEWRITER_CLASSNAME,
      FLOCK_LOGGINGFILEWRITER_CONTRACTID,
      PR_TRUE, PR_TRUE,
      nsnull);
}

static NS_METHOD
flockLoggingFileWriterUnregister(nsIComponentManager *aCompMgr,
                                 nsIFile *aPath,
                                 const char *registryLocation,
                                 const nsModuleComponentInfo *info)
{
  nsresult rv;
  nsCOMPtr<nsICategoryManager> catmgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = catmgr->DeleteCategoryEntry("flockILoggingObserver",
      FLOCK_LOGGINGFILEWRITER_CLASSNAME, PR_TRUE);

  return rv;
}


NS_GENERIC_FACTORY_CONSTRUCTOR(flockStreamUtils)
NS_GENERIC_FACTORY_CONSTRUCTOR(flockSystemInfo)
NS_GENERIC_FACTORY_CONSTRUCTOR(flockTokenizer)
NS_GENERIC_FACTORY_CONSTRUCTOR(flockCompressContent)
NS_GENERIC_FACTORY_CONSTRUCTOR(flockRDFSourceUtils)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(flockLogger, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(flockFaviconDataService)
//NS_GENERIC_FACTORY_CONSTRUCTOR(flockPriorityQueue)
//NS_GENERIC_FACTORY_CONSTRUCTOR(flockAggregator)


static nsModuleComponentInfo components[] =
{
  {
    FLOCK_RDF_SERVICE_CLASSNAME,
    FLOCK_RDF_SERVICE_CID,
    FLOCK_RDF_SERVICE_CONTRACTID,
    flockRDFServiceConstructor,
    flockRDFServiceRegister,
    flockRDFServiceUnregister,
  },

  {
    FLOCK_STREAMCOUNTSPROPAGATOR_CLASSNAME,
    FLOCK_STREAMCOUNTSPROPAGATOR_CID,
    FLOCK_STREAMCOUNTSPROPAGATOR_CONTRACTID,
    flockStreamCountsPropagatorConstructor,
    flockStreamCountsPropagatorRegister,
    flockStreamCountsPropagatorUnregister,
  },

  {
    FLOCK_STREAMUTILS_CLASSNAME,
    FLOCK_STREAMUTILS_CID,
    FLOCK_STREAMUTILS_CONTRACTID,
    flockStreamUtilsConstructor,
  },

  {
    FLOCK_SYSTEMINFO_CLASSNAME,
    FLOCK_SYSTEMINFO_CID,
    FLOCK_SYSTEMINFO_CONTRACTID,
    flockSystemInfoConstructor,
  },

  {
    FLOCK_TOKENIZER_CLASSNAME,
    FLOCK_TOKENIZER_CID,
    FLOCK_TOKENIZER_CONTRACTID,
    flockTokenizerConstructor,
  },

  {
    FLOCK_COMPRESSCONTENT_CLASSNAME,
    FLOCK_COMPRESSCONTENT_CID,
    FLOCK_COMPRESSCONTENT_CONTRACTID,
    flockCompressContentConstructor,
  },

  {
    FLOCK_RDFSOURCEUTILS_CLASSNAME,
    FLOCK_RDFSOURCEUTILS_CID,
    FLOCK_RDFSOURCEUTILS_CONTRACTID,
    flockRDFSourceUtilsConstructor,
  },

  {
    FLOCK_LOGGER_CLASSNAME,
    FLOCK_LOGGER_CID,
    FLOCK_LOGGER_CONTRACTID,
    flockLoggerConstructor,
  },

  {
    FLOCK_LOGGINGSERVICE_CLASSNAME,
    FLOCK_LOGGINGSERVICE_CID,
    FLOCK_LOGGINGSERVICE_CONTRACTID,
    flockLoggingServiceConstructor,
    flockLoggingServiceRegister,
    flockLoggingServiceUnregister,
  },

  {
    FLOCK_LOGGINGCONSOLEWRITER_CLASSNAME,
    FLOCK_LOGGINGCONSOLEWRITER_CID,
    FLOCK_LOGGINGCONSOLEWRITER_CONTRACTID,
    flockLoggingConsoleWriterConstructor,
    flockLoggingConsoleWriterRegister,
    flockLoggingConsoleWriterUnregister,
  },

  {
    FLOCK_LOGGINGFILEWRITER_CLASSNAME,
    FLOCK_LOGGINGFILEWRITER_CID,
    FLOCK_LOGGINGFILEWRITER_CONTRACTID,
    flockLoggingFileWriterConstructor,
    flockLoggingFileWriterRegister,
    flockLoggingFileWriterUnregister,
  },

  {
    FLOCK_FAVICONDATASERVICE_CLASSNAME,
    FLOCK_FAVICONDATASERVICE_CID,
    FLOCK_FAVICONDATASERVICE_CONTRACTID,
    flockFaviconDataServiceConstructor,
  },

  // about redirector
  { "about:duck",
    FLOCK_ABOUT_REDIRECTOR_CID,
    NS_ABOUT_MODULE_CONTRACTID_PREFIX "duck",
    flockAboutRedirector::Create
  },
  { "about:tutorial",
    FLOCK_ABOUT_REDIRECTOR_CID,
    NS_ABOUT_MODULE_CONTRACTID_PREFIX "tutorial",
    flockAboutRedirector::Create
  },
  { "about:myworld",
    FLOCK_ABOUT_REDIRECTOR_CID,
    NS_ABOUT_MODULE_CONTRACTID_PREFIX "myworld",
    flockAboutRedirector::Create
  },
  { "about:webdetective",
    FLOCK_ABOUT_REDIRECTOR_CID,
    NS_ABOUT_MODULE_CONTRACTID_PREFIX "webdetective",
    flockAboutRedirector::Create
  },
  { "about:flock",
    FLOCK_ABOUT_REDIRECTOR_CID,
    NS_ABOUT_MODULE_CONTRACTID_PREFIX "flock",
    flockAboutRedirector::Create
  },
  { "about:flockbuild",
    FLOCK_ABOUT_REDIRECTOR_CID,
    NS_ABOUT_MODULE_CONTRACTID_PREFIX "flockbuild",
    flockAboutRedirector::Create
  },
  { "about:flockdnsnotfound",
    FLOCK_ABOUT_REDIRECTOR_CID,
    NS_ABOUT_MODULE_CONTRACTID_PREFIX "flockdnsnotfound",
    flockAboutRedirector::Create
  },

/*
  {
    FLOCK_PRIORITYQUEUE_CLASSNAME,
    FLOCK_PRIORITYQUEUE_CID,
    FLOCK_PRIORITYQUEUE_CONTRACTID,
    flockPriorityQueueConstructor,
  },

  {
    FLOCK_AGGREGATOR_CLASSNAME,
    FLOCK_AGGREGATOR_CID,
    FLOCK_AGGREGATOR_CONTRACTID,
    flockAggregatorConstructor,
  },
*/
  { 0 }
};

NS_IMPL_NSGETMODULE(FlockCommon, components)
