/*
 * 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 "ignite_runner.h"
#include "test_utils.h"

#include <ignite/common/ignite_error.h>

#include <gtest/gtest.h>

#include <chrono>
#include <csignal>

namespace {

/** Shutdown handler that cleans up resources. */
std::function<void(int)> shutdown_handler;

/**
 * Receives OS signal and handles it.
 *
 * @param signum Signal value.
 */
void signal_handler(int signum) {
    shutdown_handler(signum);
    signal(signum, SIG_DFL);
    raise(signum);
}

} // namespace

/**
 * Sets process abortion (SIGABRT, SIGINT, SIGSEGV signals) handler.
 *
 * @param handler Abortion handler.
 */
void set_process_abort_handler(std::function<void(int)> handler) {
    shutdown_handler = std::move(handler);

    // Install signal handlers to clean up resources on early exit.
    signal(SIGABRT, signal_handler);
    signal(SIGINT, signal_handler);
    signal(SIGSEGV, signal_handler);

#ifndef _WIN32
    signal(SIGPIPE, signal_handler);
#endif
}

int main(int argc, char **argv) {
    using namespace ignite;

    if (ignite_runner::single_node_mode())
        std::cout << "Tests run in a single-node mode." << std::endl;
    else
        std::cout << "Tests run in a multi-node mode." << std::endl;

    ignite_runner runner;
    set_process_abort_handler([&](int signal) {
        std::cerr << "Caught signal " << signal << " during tests" << std::endl;

        runner.stop();
    });

    if (!check_test_node_connectable(std::chrono::seconds(5))) {
        runner.start();
        auto timeout = std::chrono::minutes(5);
        if (!check_test_node_connectable(timeout)) {
            std::cerr << "Failed to start node within timeout: " << timeout.count() << "min"  << std::endl;
            return 3;
        }
    }

    try {
        ::testing::InitGoogleTest(&argc, argv);
        [[maybe_unused]] int run_res = RUN_ALL_TESTS();
    } catch (const std::exception &err) {
        std::cerr << "Uncaught error: " << err.what() << std::endl;
        return 1;
    } catch (...) {
        std::cerr << "Unknown uncaught error" << std::endl;
        return 2;
    }

    return 0;
}
