/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#ifndef Log_H
#include "Log.h"
#endif

#ifndef Folder_H
#include "Folder.h"
#endif

#include <errno.h>
#include <inc_iostream.h>

#ifndef TeeStream_H
#include "TeeStream.h"
#endif

#ifndef IconObject_H
#include "IconObject.h"
#endif


// which platform require this one?
// (not SGI, and Linux get compiler errors
//  because of different types...!)
//extern char *sys_errlist[];
extern int sys_nerr;


Log::Log(IconObject* o):
	path_(::marstmp()),
	object_(o)
{
}

Log::~Log()
{
	path_.remove();
}

ostream& Log::global()
{
	static ostream* g = 0;
	if(g == 0)
	{
		g = &cout; // Avoid recursion
		string p = Folder::top()->logPath().str();
		g = new ofstream(p.c_str(),ios::app);
		Folder::top()->showLog();
	}
	return *g;
}

Log::operator ostream&()
{
	if(tee_.get() == 0)
	{
	
		auto_ptr<ostream> o(new ofstream(path_.str().c_str(),ios::app));
		out_ = o;
		
		auto_ptr<ostream> t(new TeeStream(global(),*out_));
		tee_ = t;


	}

	global() << '['  << object_->name() << "] ";

	return *tee_;
}

const Path& Log::path()
{
	return path_;
}

ostream& Log::syserr(ostream& s)
{
    int e = errno;
   
    if(e>0 && e < sys_nerr)
        s << " (" << sys_errlist[e] << ") " ;
    else
        s << " (errno = " << e << ") ";
    return s;
}

ostream& Log::error(IconObject* o)
{
	return info(o);
}

ostream& Log::info(IconObject* o)
{
	if(o == 0) o = Folder::top();
	return o->log();
}

ostream& Log::warning(IconObject* o)
{
	return info(o);
}

ostream& Log::info(const string& p)
{
	return global() << '[' << p << "] ";	
}

ostream& Log::warning(const string& p)
{
	return info(p);
}

ostream& Log::error(const string& p)
{
	return info(p);
}
