/*
 * 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
// fuchsia.atlassian.net/browse/ZX-560.
#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
