/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed 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.
 */

#define LOG_TAG "hidl_test_servers"

#include "hidl_test.h"

#include <android-base/logging.h>

#include <android/hardware/tests/baz/1.0/IBaz.h>

#include <hidl/LegacySupport.h>

#include <hwbinder/IPCThreadState.h>

#include <sys/wait.h>
#include <signal.h>

#include <string>
#include <utility>
#include <vector>

using ::android::hardware::tests::baz::V1_0::IBaz;

using ::android::hardware::defaultPassthroughServiceImplementation;
using ::android::hardware::IPCThreadState;

static std::vector<std::pair<std::string, pid_t>> gPidList;

void signal_handler_server(int signal) {
    if (signal == SIGTERM) {
        IPCThreadState::shutdown();
        exit(0);
    }
}

template <class T>
struct ForkServer {
    static void run(const std::string& serviceName) {
        pid_t pid;

        if ((pid = fork()) == 0) {
            // in child process
            signal(SIGTERM, signal_handler_server);
            int status = defaultPassthroughServiceImplementation<T>(serviceName);
            exit(status);
        }

        gPidList.push_back({serviceName, pid});
    }
};

static void killServer(pid_t pid, const char *serverName) {
    if (kill(pid, SIGTERM)) {
        ALOGE("Could not kill %s; errno = %d", serverName, errno);
    } else {
        int status;
        ALOGE("Waiting for %s to exit...", serverName);
        waitpid(pid, &status, 0);
        if (status != 0) {
            ALOGE("%s terminates abnormally with status %d", serverName, status);
        } else {
            ALOGE("%s killed successfully", serverName);
        }
        ALOGE("Continuing...");
    }
}

void signal_handler(int signal) {
    if (signal == SIGTERM) {
        for (auto p : gPidList) {
            killServer(p.second, p.first.c_str());
        }
        exit(0);
    }
}

int main(int /* argc */, char* /* argv */ []) {
    setenv("TREBLE_TESTING_OVERRIDE", "true", true);

    runOnEachServer<ForkServer>();

    ForkServer<IBaz>::run("dyingBaz");

    signal(SIGTERM, signal_handler);
    // Parent process should not exit before the forked child processes.
    pause();

    return 0;
}
