// Copyright 2019 The Crashpad Authors. All rights reserved.
//
// 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 "util/linux/proc_task_reader.h"

#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "gtest/gtest.h"
#include "test/multiprocess_exec.h"
#include "third_party/lss/lss.h"
#include "util/synchronization/semaphore.h"
#include "util/thread/thread.h"

namespace crashpad {
namespace test {
namespace {

bool FindThreadID(pid_t tid, const std::vector<pid_t>& threads) {
  for (const auto& thread : threads) {
    if (thread == tid) {
      return true;
    }
  }
  return false;
}

class ScopedBlockingThread : public Thread {
 public:
  ScopedBlockingThread() : tid_sem_(0), join_sem_(0), tid_(-1) {}

  ~ScopedBlockingThread() {
    join_sem_.Signal();
    Join();
  }

  pid_t ThreadID() {
    tid_sem_.Wait();
    return tid_;
  }

 private:
  void ThreadMain() override {
    tid_ = sys_gettid();
    tid_sem_.Signal();
    join_sem_.Wait();
  }

  Semaphore tid_sem_;
  Semaphore join_sem_;
  pid_t tid_;
};

TEST(ProcTaskReader, Self) {
  std::vector<pid_t> tids;
  ASSERT_TRUE(ReadThreadIDs(getpid(), &tids));
  EXPECT_TRUE(FindThreadID(getpid(), tids));
  EXPECT_TRUE(FindThreadID(sys_gettid(), tids));

  ScopedBlockingThread thread1;
  thread1.Start();

  ScopedBlockingThread thread2;
  thread2.Start();

  pid_t thread1_tid = thread1.ThreadID();
  pid_t thread2_tid = thread2.ThreadID();

  tids.clear();
  ASSERT_TRUE(ReadThreadIDs(getpid(), &tids));
  EXPECT_TRUE(FindThreadID(getpid(), tids));
  EXPECT_TRUE(FindThreadID(thread1_tid, tids));
  EXPECT_TRUE(FindThreadID(thread2_tid, tids));
}

TEST(ProcTaskReader, BadPID) {
  std::vector<pid_t> tids;
  EXPECT_FALSE(ReadThreadIDs(-1, &tids));

  tids.clear();
  EXPECT_FALSE(ReadThreadIDs(0, &tids));
}

CRASHPAD_CHILD_TEST_MAIN(ProcTaskTestChild) {
  FileHandle in = StdioFileHandle(StdioStream::kStandardInput);
  FileHandle out = StdioFileHandle(StdioStream::kStandardOutput);

  pid_t tid = getpid();
  CheckedWriteFile(out, &tid, sizeof(tid));

  tid = sys_gettid();
  CheckedWriteFile(out, &tid, sizeof(tid));

  ScopedBlockingThread thread1;
  thread1.Start();

  ScopedBlockingThread thread2;
  thread2.Start();

  tid = thread1.ThreadID();
  CheckedWriteFile(out, &tid, sizeof(tid));

  tid = thread2.ThreadID();
  CheckedWriteFile(out, &tid, sizeof(tid));

  CheckedReadFileAtEOF(in);
  return 0;
}

class ProcTaskTest : public MultiprocessExec {
 public:
  ProcTaskTest() : MultiprocessExec() {
    SetChildTestMainFunction("ProcTaskTestChild");
  }

 private:
  bool ReadIDFromChild(std::vector<pid_t>* threads) {
    pid_t tid;
    if (!LoggingReadFileExactly(ReadPipeHandle(), &tid, sizeof(tid))) {
      return false;
    }
    threads->push_back(tid);
    return true;
  }

  void MultiprocessParent() override {
    std::vector<pid_t> ids_to_find;
    for (size_t id_count = 0; id_count < 4; ++id_count) {
      ASSERT_TRUE(ReadIDFromChild(&ids_to_find));
    }

    std::vector<pid_t> threads;
    ASSERT_TRUE(ReadThreadIDs(ChildPID(), &threads));
    for (size_t index = 0; index < ids_to_find.size(); ++index) {
      SCOPED_TRACE(
          base::StringPrintf("index %zd, tid %d", index, ids_to_find[index]));
      EXPECT_TRUE(FindThreadID(ids_to_find[index], threads));
    }
  }

  DISALLOW_COPY_AND_ASSIGN(ProcTaskTest);
};

TEST(ProcTaskReader, ReadChild) {
  ProcTaskTest test;
  test.Run();
}

}  // namespace
}  // namespace test
}  // namespace crashpad
