/*
 * Copyright (C) 2018 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 <android-base/file.h>
#include <android/os/BnDumpstate.h>
#include <android/os/BnDumpstateListener.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <cutils/properties.h>
#include <fcntl.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <libgen.h>
#include <ziparchive/zip_archive.h>

#include <fstream>
#include <regex>

#include "dumpstate.h"

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

namespace android {
namespace os {
namespace dumpstate {

using ::testing::Test;
using ::std::literals::chrono_literals::operator""s;
using android::base::unique_fd;

class DumpstateListener;

namespace {

struct SectionInfo {
    std::string name;
    int32_t size_bytes;
};

sp<IDumpstate> GetDumpstateService() {
    return android::interface_cast<IDumpstate>(
        android::defaultServiceManager()->getService(String16("dumpstate")));
}

int OpenForWrite(const std::string& filename) {
    return TEMP_FAILURE_RETRY(open(filename.c_str(),
                                   O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
}

void GetEntry(const ZipArchiveHandle archive, const std::string_view entry_name, ZipEntry* data) {
    int32_t e = FindEntry(archive, entry_name, data);
    EXPECT_EQ(e, 0) << ErrorCodeString(e) << " entry name: " << entry_name;
}

// Extracts the main bugreport txt from the given archive and writes into output_fd.
void ExtractBugreport(const ZipArchiveHandle* handle, int output_fd) {
    // Read contents of main_entry.txt which is a single line indicating the name of the zip entry
    // that contains the main bugreport txt.
    ZipEntry main_entry;
    GetEntry(*handle, "main_entry.txt", &main_entry);
    std::string bugreport_txt_name;
    bugreport_txt_name.resize(main_entry.uncompressed_length);
    ExtractToMemory(*handle, &main_entry, reinterpret_cast<uint8_t*>(bugreport_txt_name.data()),
                    main_entry.uncompressed_length);

    // Read the main bugreport txt and extract to output_fd.
    ZipEntry entry;
    GetEntry(*handle, bugreport_txt_name, &entry);
    ExtractEntryToFile(*handle, &entry, output_fd);
}

bool IsSectionStart(const std::string& line, std::string* section_name) {
    static const std::regex kSectionStart = std::regex{"DUMP OF SERVICE (.*):"};
    std::smatch match;
    if (std::regex_match(line, match, kSectionStart)) {
        *section_name = match.str(1);
        return true;
    }
    return false;
}

bool IsSectionEnd(const std::string& line) {
    // Not all lines that contain "was the duration of" is a section end, but all section ends do
    // contain "was the duration of". The disambiguation can be done by the caller.
    return (line.find("was the duration of") != std::string::npos);
}

// Extracts the zipped bugreport and identifies the sections.
void ParseSections(const std::string& zip_path, std::vector<SectionInfo>* sections) {
    // Open the archive
    ZipArchiveHandle handle;
    ASSERT_EQ(OpenArchive(zip_path.c_str(), &handle), 0);

    // Extract the main entry to a temp file
    TemporaryFile tmp_binary;
    ASSERT_NE(-1, tmp_binary.fd);
    ExtractBugreport(&handle, tmp_binary.fd);

    // Read line by line and identify sections
    std::ifstream ifs(tmp_binary.path, std::ifstream::in);
    std::string line;
    int section_bytes = 0;
    std::string current_section_name;
    while (std::getline(ifs, line)) {
        std::string section_name;
        if (IsSectionStart(line, &section_name)) {
            section_bytes = 0;
            current_section_name = section_name;
        } else if (IsSectionEnd(line)) {
            if (!current_section_name.empty()) {
                sections->push_back({current_section_name, section_bytes});
            }
            current_section_name = "";
        } else if (!current_section_name.empty()) {
            section_bytes += line.length();
        }
    }

    CloseArchive(handle);
}

}  // namespace

/**
 * Listens to bugreport progress and updates the user by writing the progress to STDOUT. All the
 * section details generated by dumpstate are added to a vector to be used by Tests later.
 */
class DumpstateListener : public BnDumpstateListener {
  public:
    DumpstateListener(int fd, std::shared_ptr<std::vector<SectionInfo>> sections)
        : out_fd_(fd), sections_(sections) {
    }

    DumpstateListener(int fd) : out_fd_(fd) {
    }

    binder::Status onProgress(int32_t progress) override {
        dprintf(out_fd_, "\rIn progress %d", progress);
        return binder::Status::ok();
    }

    binder::Status onError(int32_t error_code) override {
        std::lock_guard<std::mutex> lock(lock_);
        error_code_ = error_code;
        dprintf(out_fd_, "\rError code %d", error_code);
        return binder::Status::ok();
    }

    binder::Status onFinished() override {
        std::lock_guard<std::mutex> lock(lock_);
        is_finished_ = true;
        dprintf(out_fd_, "\rFinished");
        return binder::Status::ok();
    }

    binder::Status onScreenshotTaken(bool success) override {
        std::lock_guard<std::mutex> lock(lock_);
        dprintf(out_fd_, "\rResult of taking screenshot: %s", success ? "success" : "failure");
        return binder::Status::ok();
    }

    binder::Status onUiIntensiveBugreportDumpsFinished() override {
        std::lock_guard <std::mutex> lock(lock_);
        dprintf(out_fd_, "\rUi intensive bugreport dumps finished");
        return binder::Status::ok();
    }

    bool getIsFinished() {
        std::lock_guard<std::mutex> lock(lock_);
        return is_finished_;
    }

    int getErrorCode() {
        std::lock_guard<std::mutex> lock(lock_);
        return error_code_;
    }

  private:
    int out_fd_;
    int error_code_ = -1;
    bool is_finished_ = false;
    std::shared_ptr<std::vector<SectionInfo>> sections_;
    std::mutex lock_;
};

/**
 * Generates bug report and provide access to the bug report file and other info for other tests.
 * Since bug report generation is slow, the bugreport is only generated once.
 */
class ZippedBugreportGenerationTest : public Test {
  public:
    static std::shared_ptr<std::vector<SectionInfo>> sections;
    static Dumpstate& ds;
    static std::chrono::milliseconds duration;
    static void GenerateBugreport() {
        // clang-format off
        char* argv[] = {
            (char*)"dumpstate"
        };
        // clang-format on
        sp<DumpstateListener> listener(new DumpstateListener(dup(fileno(stdout)), sections));
        ds.listener_ = listener;
        auto start = std::chrono::steady_clock::now();
        ds.ParseCommandlineAndRun(ARRAY_SIZE(argv), argv);
        auto end = std::chrono::steady_clock::now();
        duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    }

    static const std::string getZipFilePath() {
        return ds.GetPath(".zip");
    }
};
std::shared_ptr<std::vector<SectionInfo>> ZippedBugreportGenerationTest::sections =
    std::make_shared<std::vector<SectionInfo>>();
Dumpstate& ZippedBugreportGenerationTest::ds = Dumpstate::GetInstance();
std::chrono::milliseconds ZippedBugreportGenerationTest::duration = 0s;

TEST_F(ZippedBugreportGenerationTest, IsGeneratedWithoutErrors) {
    GenerateBugreport();
    EXPECT_EQ(access(getZipFilePath().c_str(), F_OK), 0);
}

TEST_F(ZippedBugreportGenerationTest, Is1MBMBinSize) {
    struct stat st;
    EXPECT_EQ(stat(getZipFilePath().c_str(), &st), 0);
    EXPECT_GE(st.st_size, 1000000 /* 1MB */);
}

TEST_F(ZippedBugreportGenerationTest, TakesBetween30And300Seconds) {
    EXPECT_GE(duration, 30s) << "Expected completion in more than 30s. Actual time "
                             << duration.count() << " s.";
    EXPECT_LE(duration, 300s) << "Expected completion in less than 300s. Actual time "
                              << duration.count() << " s.";
}

/**
 * Run tests on contents of zipped bug report.
 */
class ZippedBugReportContentsTest : public Test {
  public:
    ZipArchiveHandle handle;
    void SetUp() {
        ASSERT_EQ(OpenArchive(ZippedBugreportGenerationTest::getZipFilePath().c_str(), &handle), 0);
    }
    void TearDown() {
        CloseArchive(handle);
    }

    void FileExists(const char* filename, uint32_t minsize,
                    uint32_t maxsize = std::numeric_limits<uint32_t>::max()) {
        ZipEntry entry;
        GetEntry(handle, filename, &entry);
        EXPECT_GT(entry.uncompressed_length, minsize);
        EXPECT_LT(entry.uncompressed_length, maxsize);
    }
};

TEST_F(ZippedBugReportContentsTest, ContainsMainEntry) {
    ZipEntry main_entry;
    // contains main entry name file
    GetEntry(handle, "main_entry.txt", &main_entry);

    std::string bugreport_txt_name;
    bugreport_txt_name.resize(main_entry.uncompressed_length);
    ExtractToMemory(handle, &main_entry, reinterpret_cast<uint8_t*>(bugreport_txt_name.data()),
                    main_entry.uncompressed_length);

    // contains main entry file
    FileExists(bugreport_txt_name.c_str(), 1000000U);
}

TEST_F(ZippedBugReportContentsTest, ContainsVersion) {
    ZipEntry entry;
    // contains main entry name file
    GetEntry(handle, "version.txt", &entry);

    char* buf = new char[entry.uncompressed_length + 1];
    ExtractToMemory(handle, &entry, (uint8_t*)buf, entry.uncompressed_length);
    buf[entry.uncompressed_length] = 0;
    EXPECT_STREQ(buf, ZippedBugreportGenerationTest::ds.version_.c_str());
    delete[] buf;
}

TEST_F(ZippedBugReportContentsTest, ContainsBoardSpecificFiles) {
    // TODO(b/160109027): cf_x86_phone-userdebug does not dump them.
    // FileExists("dumpstate_board.bin", 1000000U, 80000000U);
    // FileExists("dumpstate_board.txt", 100000U, 1000000U);
}

TEST_F(ZippedBugReportContentsTest, ContainsProtoFile) {
    FileExists("proto/activity.proto", 100000U, 1000000U);
}

// Spot check on some files pulled from the file system
TEST_F(ZippedBugReportContentsTest, ContainsSomeFileSystemFiles) {
    // FS/proc/*/mountinfo size > 0
    FileExists("FS/proc/1/mountinfo", 0U, 100000U);

    // FS/data/misc/profiles/cur/0/*/primary.prof should exist. Also, since dumpstate only adds
    // profiles to the zip in the non-user build, a build checking is necessary here.
    if (!PropertiesHelper::IsUserBuild()) {
        ZipEntry entry;
        GetEntry(handle, "FS/data/misc/profiles/cur/0/com.android.phone/primary.prof", &entry);
    }
}

/**
 * Runs tests on section data generated by dumpstate and captured by DumpstateListener.
 */
class BugreportSectionTest : public Test {
  public:
    ZipArchiveHandle handle;

    void SetUp() {
        ASSERT_EQ(OpenArchive(ZippedBugreportGenerationTest::getZipFilePath().c_str(), &handle), 0);
    }

    void TearDown() {
        CloseArchive(handle);
    }

    static void SetUpTestCase() {
        ParseSections(ZippedBugreportGenerationTest::getZipFilePath().c_str(),
                      ZippedBugreportGenerationTest::sections.get());
    }

    int numMatches(const std::string& substring) {
        int matches = 0;
        for (auto const& section : *ZippedBugreportGenerationTest::sections) {
            if (section.name.find(substring) != std::string::npos) {
                matches++;
            }
        }
        return matches;
    }

    void SectionExists(const std::string& sectionName, int minsize) {
        for (auto const& section : *ZippedBugreportGenerationTest::sections) {
            if (sectionName == section.name) {
                EXPECT_GE(section.size_bytes, minsize) << " for section:" << sectionName;
                return;
            }
        }
        FAIL() << sectionName << " not found.";
    }

    /**
     * Whether or not the content of the section is injected by other commands.
     */
    bool IsContentInjectedByOthers(const std::string& line) {
        // Command header such as `------ APP ACTIVITIES (/system/bin/dumpsys activity -v) ------`.
        static const std::regex kCommandHeader = std::regex{"------ .+ \\(.+\\) ------"};
        std::smatch match;
        if (std::regex_match(line, match, kCommandHeader)) {
          return true;
        }
        return false;
    }
};

TEST_F(BugreportSectionTest, Atleast3CriticalDumpsysSectionsGenerated) {
    int numSections = numMatches("CRITICAL");
    EXPECT_GE(numSections, 3);
}

TEST_F(BugreportSectionTest, Atleast2HighDumpsysSectionsGenerated) {
    int numSections = numMatches("HIGH");
    EXPECT_GE(numSections, 2);
}

TEST_F(BugreportSectionTest, Atleast50NormalDumpsysSectionsGenerated) {
    int allSections = ZippedBugreportGenerationTest::sections->size();
    int criticalSections = numMatches("CRITICAL");
    int highSections = numMatches("HIGH");
    int normalSections = allSections - criticalSections - highSections;

    EXPECT_GE(normalSections, 50) << "Total sections less than 50 (Critical:" << criticalSections
                                  << "High:" << highSections << "Normal:" << normalSections << ")";
}

// Test if some critical sections are being generated.
TEST_F(BugreportSectionTest, CriticalSurfaceFlingerSectionGenerated) {
    SectionExists("CRITICAL SurfaceFlinger", /* bytes= */ 10000);
}

TEST_F(BugreportSectionTest, ActivitySectionsGenerated) {
    SectionExists("CRITICAL activity", /* bytes= */ 5000);
    SectionExists("activity", /* bytes= */ 10000);
}

TEST_F(BugreportSectionTest, CpuinfoSectionGenerated) {
    SectionExists("CRITICAL cpuinfo", /* bytes= */ 1000);
}

TEST_F(BugreportSectionTest, WindowSectionGenerated) {
    SectionExists("CRITICAL window", /* bytes= */ 20000);
}

TEST_F(BugreportSectionTest, ConnectivitySectionsGenerated) {
    SectionExists("connectivity", /* bytes= */ 5000);
}

TEST_F(BugreportSectionTest, MeminfoSectionGenerated) {
    SectionExists("HIGH meminfo", /* bytes= */ 100000);
}

TEST_F(BugreportSectionTest, BatteryStatsSectionGenerated) {
    SectionExists("batterystats", /* bytes= */ 1000);
}

TEST_F(BugreportSectionTest, DISABLED_WifiSectionGenerated) {
    SectionExists("wifi", /* bytes= */ 100000);
}

TEST_F(BugreportSectionTest, NoInjectedContentByOtherCommand) {
    // Extract the main entry to a temp file
    TemporaryFile tmp_binary;
    ASSERT_NE(-1, tmp_binary.fd);
    ExtractBugreport(&handle, tmp_binary.fd);

    // Read line by line and identify sections
    std::ifstream ifs(tmp_binary.path, std::ifstream::in);
    std::string line;
    std::string current_section_name;
    while (std::getline(ifs, line)) {
        std::string section_name;
        if (IsSectionStart(line, &section_name)) {
            current_section_name = section_name;
        } else if (IsSectionEnd(line)) {
            current_section_name = "";
        } else if (!current_section_name.empty()) {
            EXPECT_FALSE(IsContentInjectedByOthers(line));
        }
    }
}

class DumpstateBinderTest : public Test {
  protected:
    void SetUp() override {
        // In case there is a stray service, stop it first.
        property_set("ctl.stop", "bugreportd");
        // dry_run results in a faster bugreport.
        property_set("dumpstate.dry_run", "true");
        // We need to receive some async calls later. Ensure we have binder threads.
        ProcessState::self()->startThreadPool();
    }

    void TearDown() override {
        property_set("ctl.stop", "bugreportd");
        property_set("dumpstate.dry_run", "");

        unlink("/data/local/tmp/tmp.zip");
        unlink("/data/local/tmp/tmp.png");
    }

    // Waits until listener gets the callbacks.
    void WaitTillExecutionComplete(DumpstateListener* listener) {
        // Wait till one of finished, error or timeout.
        static const int kBugreportTimeoutSeconds = 120;
        int i = 0;
        while (!listener->getIsFinished() && listener->getErrorCode() == -1 &&
               i < kBugreportTimeoutSeconds) {
            sleep(1);
            i++;
        }
    }
};

TEST_F(DumpstateBinderTest, Baseline) {
    // In the beginning dumpstate binder service is not running.
    sp<android::os::IDumpstate> ds_binder(GetDumpstateService());
    EXPECT_EQ(ds_binder, nullptr);

    // Start bugreportd, which runs dumpstate binary with -w; which starts dumpstate service
    // and makes it wait.
    property_set("dumpstate.dry_run", "true");
    property_set("ctl.start", "bugreportd");

    // Now we are able to retrieve dumpstate binder service.
    ds_binder = GetDumpstateService();
    EXPECT_NE(ds_binder, nullptr);

    // Prepare arguments
    unique_fd bugreport_fd(OpenForWrite("/bugreports/tmp.zip"));
    unique_fd screenshot_fd(OpenForWrite("/bugreports/tmp.png"));

    EXPECT_NE(bugreport_fd.get(), -1);
    EXPECT_NE(screenshot_fd.get(), -1);

    sp<DumpstateListener> listener(new DumpstateListener(dup(fileno(stdout))));
    android::binder::Status status =
        ds_binder->startBugreport(123, "com.dummy.package", std::move(bugreport_fd), std::move(screenshot_fd),
                                  Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, listener, true);
    // startBugreport is an async call. Verify binder call succeeded first, then wait till listener
    // gets expected callbacks.
    EXPECT_TRUE(status.isOk());
    WaitTillExecutionComplete(listener.get());

    // Bugreport generation requires user consent, which we cannot get in a test set up,
    // so instead of getting is_finished_, we are more likely to get a consent error.
    EXPECT_TRUE(
        listener->getErrorCode() == IDumpstateListener::BUGREPORT_ERROR_USER_DENIED_CONSENT ||
        listener->getErrorCode() == IDumpstateListener::BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT);

    // The service should have died on its own, freeing itself up for a new invocation.
    sleep(2);
    ds_binder = GetDumpstateService();
    EXPECT_EQ(ds_binder, nullptr);
}

TEST_F(DumpstateBinderTest, ServiceDies_OnInvalidInput) {
    // Start bugreportd, which runs dumpstate binary with -w; which starts dumpstate service
    // and makes it wait.
    property_set("ctl.start", "bugreportd");
    sp<android::os::IDumpstate> ds_binder(GetDumpstateService());
    EXPECT_NE(ds_binder, nullptr);

    // Prepare arguments
    unique_fd bugreport_fd(OpenForWrite("/data/local/tmp/tmp.zip"));
    unique_fd screenshot_fd(OpenForWrite("/data/local/tmp/tmp.png"));

    EXPECT_NE(bugreport_fd.get(), -1);
    EXPECT_NE(screenshot_fd.get(), -1);

    // Call startBugreport with bad arguments.
    sp<DumpstateListener> listener(new DumpstateListener(dup(fileno(stdout))));
    android::binder::Status status =
        ds_binder->startBugreport(123, "com.dummy.package", std::move(bugreport_fd), std::move(screenshot_fd),
                                  2000,  // invalid bugreport mode
                                  listener, false);
    EXPECT_EQ(listener->getErrorCode(), IDumpstateListener::BUGREPORT_ERROR_INVALID_INPUT);

    // The service should have died, freeing itself up for a new invocation.
    sleep(2);
    ds_binder = GetDumpstateService();
    EXPECT_EQ(ds_binder, nullptr);
}

TEST_F(DumpstateBinderTest, SimultaneousBugreportsNotAllowed) {
    // Start bugreportd, which runs dumpstate binary with -w; which starts dumpstate service
    // and makes it wait.
    property_set("dumpstate.dry_run", "true");
    property_set("ctl.start", "bugreportd");
    sp<android::os::IDumpstate> ds_binder(GetDumpstateService());
    EXPECT_NE(ds_binder, nullptr);

    // Prepare arguments
    unique_fd bugreport_fd(OpenForWrite("/data/local/tmp/tmp.zip"));
    unique_fd bugreport_fd2(dup(bugreport_fd.get()));
    unique_fd screenshot_fd(OpenForWrite("/data/local/tmp/tmp.png"));
    unique_fd screenshot_fd2(dup(screenshot_fd.get()));

    EXPECT_NE(bugreport_fd.get(), -1);
    EXPECT_NE(bugreport_fd2.get(), -1);
    EXPECT_NE(screenshot_fd.get(), -1);
    EXPECT_NE(screenshot_fd2.get(), -1);

    sp<DumpstateListener> listener1(new DumpstateListener(dup(fileno(stdout))));
    android::binder::Status status =
        ds_binder->startBugreport(123, "com.dummy.package", std::move(bugreport_fd), std::move(screenshot_fd),
                                  Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, listener1, true);
    EXPECT_TRUE(status.isOk());

    // try to make another call to startBugreport. This should fail.
    sp<DumpstateListener> listener2(new DumpstateListener(dup(fileno(stdout))));
    status = ds_binder->startBugreport(123, "com.dummy.package", std::move(bugreport_fd2), std::move(screenshot_fd2),
                                       Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, listener2, true);
    EXPECT_FALSE(status.isOk());
    WaitTillExecutionComplete(listener2.get());
    EXPECT_EQ(listener2->getErrorCode(),
              IDumpstateListener::BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS);

    // Meanwhile the first call works as expected. Service should not die in this case.
    WaitTillExecutionComplete(listener1.get());

    // Bugreport generation requires user consent, which we cannot get in a test set up,
    // so instead of getting is_finished_, we are more likely to get a consent error.
    EXPECT_TRUE(
        listener1->getErrorCode() == IDumpstateListener::BUGREPORT_ERROR_USER_DENIED_CONSENT ||
        listener1->getErrorCode() == IDumpstateListener::BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT);
}

}  // namespace dumpstate
}  // namespace os
}  // namespace android
