/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <iostream>		// for `cout`, `endl`
#include <cstdlib>		// for `exit()`, `EXIT_FAILURE`
#include <unistd.h>		// for `readlink`, `chdir`
#include <libgen.h> 	// for `dirname`
#include <limits.h>		// for `PATH_MAX`
#include <iomanip>		// for `put_time()`
#include <ctime>		// for `time()`
#include <fuzzer/FuzzedDataProvider.h>
#include <log4cxx/propertyconfigurator.h>
#include <log4cxx/appenderskeleton.h>

using namespace LOG4CXX_NS;

namespace LOG4CXX_NS::fuzzer {

/**
 * Appender encoding incoming log events using the provided layout.
 * It is intended for appender-agnostic fuzzing.
 */
class EncodingAppender : public AppenderSkeleton {

public:
	DECLARE_LOG4CXX_OBJECT(EncodingAppender)
	BEGIN_LOG4CXX_CAST_MAP()
	LOG4CXX_CAST_ENTRY(EncodingAppender)
	LOG4CXX_CAST_ENTRY_CHAIN(AppenderSkeleton)
	END_LOG4CXX_CAST_MAP()

	EncodingAppender() : AppenderSkeleton() {}

	EncodingAppender(const LayoutPtr& layout) : AppenderSkeleton(layout) {}

	void close() override {}

	bool requiresLayout() const override {
		return true;
	}

	void append(const spi::LoggingEventPtr& event, helpers::Pool& pool) override {
		LogString msg;
		getLayout()->format(msg, event, pool);
	}

	void setOption(const LogString& option, const LogString& value) override {}

}; // class

IMPLEMENT_LOG4CXX_OBJECT(EncodingAppender)

LOG4CXX_PTR_DEF(EncodingAppender);

} // namespace

static std::time_t logTime;
static std::tm* logTimeBuffer;
#define LOG(stream) \
	logTime = std::time(nullptr); \
	logTimeBuffer = std::localtime(&logTime); \
	stream << std::put_time(logTimeBuffer, "%Y-%m-%d %H:%M:%S") << " [" << __FILE_NAME__ << ":" << __LINE__ << "] "

static void findExecutablePath(char* buffer) {
    ssize_t length = readlink("/proc/self/exe", buffer, PATH_MAX);
    if (length == -1) {
    	LOG(std::cerr) << "ERROR: Failed to find the executable path" << std::endl;
		exit(EXIT_FAILURE);
	}
	buffer[length] = '\0';
}

static void chdirExecutableHome() {
    char executablePath[PATH_MAX];
    findExecutablePath(executablePath);
    char* executableHome = dirname(executablePath);
	if (chdir(executableHome) != 0) {
		LOG(std::cerr) << "DEBUG: Executable path: " << executablePath << std::endl;
		LOG(std::cerr) << "DEBUG: Executable home: " << executableHome << std::endl;
		LOG(std::cerr) << "ERROR: Failed to `chdir()` the executable path" << std::endl;
	}
}

static int INITIALIZED = 0;

static void init() {
	if (INITIALIZED != 0) {
		return;
	}
	LOG(std::cout) << "INFO: Produced using the Git commit ID: " << GIT_COMMIT_ID << std::endl;
	chdirExecutableHome();
	PropertyConfigurator::configure("PatternLayoutFuzzer.properties");
	INITIALIZED = 1;
}

#define MAX_STRING_LENGTH 512

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
	init();
	LoggerPtr logger = Logger::getRootLogger();
  	FuzzedDataProvider dataProvider(data, size);
  	while (dataProvider.remaining_bytes() > 0) {
  		std::string message = dataProvider.ConsumeRandomLengthString(MAX_STRING_LENGTH);
    	LOG4CXX_INFO(logger, message);
    }
  	return 0;
}
