/*
 * Copyright (C) 2020 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.
 */

#include <signal.h>
#include <sys/time.h>
#include <unistd.h>

#include <algorithm>
#include <mutex>
#include <thread>

#include <android-base/logging.h>
#include <android-base/parsebool.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/thread_annotations.h>

#include "property_monitor.h"

static constexpr char kAdbWatchdogProperty[] = "persist.adb.watchdog";
static constexpr char kTestHarnessProperty[] = "persist.sys.test_harness";

static constexpr unsigned int kDefaultAdbWatchdogTimeoutSeconds = 600;
static unsigned int g_watchdog_timeout_seconds;

static std::mutex g_watchdog_mutex [[clang::no_destroy]];

// The watchdog is "running" when it's enabled via property and there are no connected clients.
static bool g_watchdog_running GUARDED_BY(g_watchdog_mutex) = false;

static PropertyMonitor g_property_monitor [[clang::no_destroy]];

static void UpdateWatchdog() REQUIRES(g_watchdog_mutex) {
    static std::once_flag once;
    std::call_once(once, []() {
        signal(SIGALRM, [](int) {
            execl("/system/bin/reboot", "/system/bin/reboot", "bootloader", nullptr);
        });
    });

    static bool alarm_set = false;

    static auto Arm = []() {
        LOG(INFO) << "adb watchdog armed, triggering in " << g_watchdog_timeout_seconds
                  << " seconds";
        alarm(g_watchdog_timeout_seconds);
        alarm_set = true;
    };

    static auto Disarm = []() {
        unsigned int previous = alarm(0);
        if (previous != 0) {
            LOG(INFO) << "adb watchdog disarmed with " << previous << " seconds left";
        }
        alarm_set = false;
    };

    bool watchdog_enabled = android::base::GetBoolProperty(
            kAdbWatchdogProperty, android::base::GetBoolProperty(kTestHarnessProperty, false));
    if (!watchdog_enabled) {
        if (alarm_set) {
            Disarm();
        }
        return;
    }

    if (g_watchdog_running) {
        if (!alarm_set) {
            Arm();
        }
    } else {
        Disarm();
    }
}

namespace watchdog {

void Start() {
    std::lock_guard<std::mutex> lock(g_watchdog_mutex);
    g_watchdog_running = true;
    UpdateWatchdog();
}

void Stop() {
    std::lock_guard<std::mutex> lock(g_watchdog_mutex);
    g_watchdog_running = false;
    UpdateWatchdog();
}

void Initialize() {
    for (auto& property : {kAdbWatchdogProperty, kTestHarnessProperty}) {
        g_property_monitor.Add(property, [property](std::string value) {
            LOG(INFO) << property << " set to '" << value << "'";

            std::lock_guard<std::mutex> lock(g_watchdog_mutex);
            UpdateWatchdog();
            return true;
        });
    }

    g_property_monitor.Add("persist.adb.watchdog.timeout_secs", [](std::string value) {
        // This presumably isn't going to change while the watchdog is armed,
        // so we don't need to recalculate a timer.
        {
            std::lock_guard<std::mutex> lock(g_watchdog_mutex);
            if (!android::base::ParseUint(value, &g_watchdog_timeout_seconds)) {
                g_watchdog_timeout_seconds = kDefaultAdbWatchdogTimeoutSeconds;
            }
        }

        LOG(INFO) << "adb watchdog timeout set to " << g_watchdog_timeout_seconds << " seconds";
        return true;
    });

    Start();
    std::thread([]() { g_property_monitor.Run(); }).detach();
}

}  // namespace watchdog
