/*
 * 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.
 */

#include "perfetto/ext/base/utils.h"

#include "perfetto/base/build_config.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#else
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#endif

#include <stdint.h>

#include <algorithm>
#include <random>
#include <thread>

#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/pipe.h"
#include "perfetto/ext/base/temp_file.h"
#include "test/gtest_and_gmock.h"

namespace perfetto {
namespace base {
namespace {

TEST(UtilsTest, ArraySize) {
  char char_arr_1[1];
  char char_arr_4[4];
  EXPECT_EQ(1u, ArraySize(char_arr_1));
  EXPECT_EQ(4u, ArraySize(char_arr_4));

  int32_t int32_arr_1[1];
  int32_t int32_arr_4[4];
  EXPECT_EQ(1u, ArraySize(int32_arr_1));
  EXPECT_EQ(4u, ArraySize(int32_arr_4));

  uint64_t int64_arr_1[1];
  uint64_t int64_arr_4[4];
  EXPECT_EQ(1u, ArraySize(int64_arr_1));
  EXPECT_EQ(4u, ArraySize(int64_arr_4));

  char kString[] = "foo";
  EXPECT_EQ(4u, ArraySize(kString));

  struct Bar {
    int32_t a;
    int32_t b;
  };
  Bar bar_1[1];
  Bar bar_4[4];
  EXPECT_EQ(1u, ArraySize(bar_1));
  EXPECT_EQ(4u, ArraySize(bar_4));
}

TEST(UtilsTest, PipeBlockingRW) {
  Pipe pipe = Pipe::Create();
  std::string expected;
  expected.resize(1024 * 512u);
  for (size_t i = 0; i < expected.size(); i++)
    expected[i] = '!' + static_cast<char>(i % 64);

  std::thread writer([&] {
    std::string tx = expected;
    std::minstd_rand0 rnd_engine(0);

    while (!tx.empty()) {
      size_t wsize = static_cast<size_t>(rnd_engine() % 4096) + 1;
      wsize = std::min(wsize, tx.size());
      WriteAllHandle(*pipe.wr, &tx[0], wsize);
      tx.erase(0, wsize);
    }
    pipe.wr.reset();
  });

  std::string actual;
  ASSERT_TRUE(ReadPlatformHandle(*pipe.rd, &actual));
  ASSERT_EQ(actual, expected);
  writer.join();
}

// Tests that WriteAllHandle and ReadPlatformHandle work as advertised.
// TODO(primiano): normalize File handling on Windows. Right now some places
// use POSIX-compat APIs that use "int" file descriptors (_open, _read, _write),
// some other places use WINAPI files (CreateFile(), ReadFile()), where the file
// is a HANDLE.
TEST(UtilsTest, ReadWritePlatformHandle) {
  auto tmp = TempDir::Create();
  std::string payload = "foo\nbar\0baz\r\nqux";
  std::string tmp_path = tmp.path() + "/temp.txt";

  // Write a file using PlatformHandle. Note: the {} blocks are to make sure
  // that the file is automatically closed via RAII before being reopened.
  {
    ScopedPlatformHandle handle {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
      ::CreateFileA(tmp_path.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,
                    FILE_ATTRIBUTE_NORMAL, nullptr)
#else
      OpenFile(tmp_path, O_WRONLY | O_CREAT | O_TRUNC, 0644)
#endif
    };
    ASSERT_TRUE(handle);
    ASSERT_EQ(WriteAllHandle(*handle, payload.data(), payload.size()),
              static_cast<ssize_t>(payload.size()));
  }

  // Read it back.
  {
    ScopedPlatformHandle handle {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
      ::CreateFileA(tmp_path.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING,
                    FILE_ATTRIBUTE_NORMAL, nullptr)
#else
      OpenFile(tmp_path, O_RDONLY)
#endif
    };
    ASSERT_TRUE(handle);
    std::string actual = "preserve_existing:";
    ASSERT_TRUE(ReadPlatformHandle(*handle, &actual));
    ASSERT_EQ(actual, "preserve_existing:" + payload);
  }

  ASSERT_EQ(remove(tmp_path.c_str()), 0);
}

// Fuchsia doesn't currently support sigaction(), see
// https://fxbug.dev/42105390 .
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
TEST(UtilsTest, EintrWrapper) {
  Pipe pipe = Pipe::Create();

  struct sigaction sa = {};
  struct sigaction old_sa = {};

// Glibc headers for sa_sigaction trigger this.
#pragma GCC diagnostic push
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
#endif
  sa.sa_sigaction = [](int, siginfo_t*, void*) {};
#pragma GCC diagnostic pop

  ASSERT_EQ(0, sigaction(SIGUSR2, &sa, &old_sa));
  int parent_pid = getpid();
  pid_t pid = fork();
  ASSERT_NE(-1, pid);
  if (pid == 0 /* child */) {
    usleep(5000);
    kill(parent_pid, SIGUSR2);
    ignore_result(WriteAll(*pipe.wr, "foo\0", 4));
    _exit(0);
  }

  char buf[6] = {};
  EXPECT_EQ(4, PERFETTO_EINTR(read(*pipe.rd, buf, sizeof(buf))));
  EXPECT_TRUE(close(*pipe.rd) == 0 || errno == EINTR);
  pipe.wr.reset();

  // A 2nd close should fail with the proper errno.
  int res = close(*pipe.rd);
  auto err = errno;
  EXPECT_EQ(-1, res);
  EXPECT_EQ(EBADF, err);
  pipe.rd.release();

  // Restore the old handler.
  sigaction(SIGUSR2, &old_sa, nullptr);
}
#endif  // LINUX | ANDROID | APPLE

TEST(UtilsTest, Align) {
  EXPECT_EQ(0u, AlignUp<4>(0));
  EXPECT_EQ(4u, AlignUp<4>(1));
  EXPECT_EQ(4u, AlignUp<4>(3));
  EXPECT_EQ(4u, AlignUp<4>(4));
  EXPECT_EQ(8u, AlignUp<4>(5));
  EXPECT_EQ(0u, AlignUp<16>(0));
  EXPECT_EQ(16u, AlignUp<16>(1));
  EXPECT_EQ(16u, AlignUp<16>(15));
  EXPECT_EQ(16u, AlignUp<16>(16));
  EXPECT_EQ(32u, AlignUp<16>(17));
  EXPECT_EQ(0xffffff00u, AlignUp<16>(0xffffff00 - 1));
}

TEST(UtilsTest, HexDump) {
  char input[] = {0x00, 0x00, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
                  'h',  'i',  'j', 'k', 'l', 'm', 'n', 'o', 'p'};

  std::string output = HexDump(input, sizeof(input));

  EXPECT_EQ(
      output,
      R"(00000000: 00 00 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E   ..abcdefghijklmn
00000010: 6F 70                                             op
)");
}

}  // namespace
}  // namespace base
}  // namespace perfetto
