// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <ddk/platform-defs.h>
#include <lib/devmgr-integration-test/fixture.h>
#include <lib/devmgr-launcher/launch.h>
#include <lib/zx/vmo.h>
#include <libzbi/zbi-cpp.h>
#include <unittest/unittest.h>
#include <zircon/boot/image.h>
#include <zircon/status.h>

using devmgr_integration_test::IsolatedDevmgr;
using devmgr_integration_test::RecursiveWaitForFile;

namespace {

constexpr char kBoardName[] = "pbus-test";

zbi_platform_id_t kPlatformId = [](){
    zbi_platform_id_t plat_id = {};
    plat_id.vid = PDEV_VID_TEST;
    plat_id.pid = PDEV_PID_PBUS_TEST;
    strcpy(plat_id.board_name, kBoardName);
    return plat_id;
}();

bool GetBootData(zx::vmo* bootdata_out) {
    BEGIN_HELPER;
    uint8_t zbi_buf[1024];
    zbi::Zbi zbi(zbi_buf, 1024);
    ASSERT_EQ(zbi.Reset(), ZBI_RESULT_OK);
    ASSERT_EQ(zbi.AppendSection(sizeof(kPlatformId), ZBI_TYPE_PLATFORM_ID, 0, ZBI_FLAG_VERSION,
                                &kPlatformId),
              ZBI_RESULT_OK);
    zx::vmo zbi_vmo;
    ASSERT_EQ(zx::vmo::create(zbi.Length(), 0, &zbi_vmo), ZX_OK);
    ASSERT_EQ(zbi_vmo.write(zbi.Base(), 0, zbi.Length()), ZX_OK);

    *bootdata_out = std::move(zbi_vmo);
    END_HELPER;
}

bool enumeration_test() {
    BEGIN_TEST;

    devmgr_launcher::Args args;
    args.sys_device_driver = "/boot/driver/platform-bus.so";
    args.driver_search_paths.push_back("/boot/driver");
    ASSERT_TRUE(GetBootData(&args.bootdata));

    fbl::unique_ptr<IsolatedDevmgr> devmgr;
    ASSERT_EQ(IsolatedDevmgr::Create(std::move(args), &devmgr), ZX_OK);

    fbl::unique_fd fd;
    ASSERT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform",
                                   zx::deadline_after(zx::sec(5)), &fd),
              ZX_OK);

    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/test-board",
                                   zx::deadline_after(zx::sec(5)), &fd),
              ZX_OK);

    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/11:01:1",
                                   zx::deadline_after(zx::sec(5)), &fd),
              ZX_OK);

    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/11:01:1/child-1",
                                   zx::deadline_after(zx::sec(5)), &fd),
              ZX_OK);

    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/11:01:1/child-1/child-2",
                                   zx::deadline_after(zx::sec(5)), &fd),
              ZX_OK);

    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/11:01:1/child-1/child-3",
                                   zx::deadline_after(zx::sec(5)), &fd),
              ZX_OK);

    const int dirfd = devmgr->devfs_root().get();
    struct stat st;
    EXPECT_EQ(fstatat(dirfd, "sys/platform/test-board", &st, 0), 0);
    EXPECT_EQ(fstatat(dirfd, "sys/platform/11:01:1", &st, 0), 0);
    EXPECT_EQ(fstatat(dirfd, "sys/platform/11:01:1/child-1", &st, 0), 0);
    EXPECT_EQ(fstatat(dirfd, "sys/platform/11:01:1/child-1/child-2", &st, 0), 0);
    EXPECT_EQ(fstatat(dirfd, "sys/platform/11:01:1/child-1/child-3", &st, 0), 0);

    END_TEST;
}

} // namespace

BEGIN_TEST_CASE(pbus_tests)
RUN_TEST(enumeration_test)
END_TEST_CASE(pbus_tests);

int main(int argc, char** argv) {
    return unittest_run_all_tests(argc, argv) ? 0 : -1;
}
