// Copyright 2015 The Bazel 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 <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <vector>

#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/blaze_util_platform.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/file_platform.h"
#include "gtest/gtest.h"

namespace blaze {

using std::string;

class BlazeUtilTest : public ::testing::Test {
 protected:
  BlazeUtilTest() {
  }

  virtual ~BlazeUtilTest() {
  }

  static void ForkAndWrite(int fds[], string input1, string input2) {
    int r = fork();
    if (r == 0) {
      close(fds[0]);
      write(fds[1], input1.c_str(), input1.size());
      usleep(500);  // sleep for 50ms
      write(fds[1], input2.c_str(), input2.size());
      close(fds[1]);
      exit(0);
    } else if (r < 0) {
      perror("fork()");
      FAIL();
    } else {
      close(fds[1]);
    }
  }

  static int WriteFileDescriptor2(string input1, string input2) {
    // create a fd for the input string
    int fds[2];
    if (pipe(fds) == -1) {
      return -1;
    }
    if (fcntl(fds[0], F_SETFL, O_NONBLOCK) == -1
        || fcntl(fds[1], F_SETFL, O_NONBLOCK) == -1) {
      return -1;
    }
    if (input2.size() > 0) {
      ForkAndWrite(fds, input1, input2);
    } else {
      write(fds[1], input1.c_str(), input1.size());
      close(fds[1]);
    }
    return fds[0];
  }

  static void AssertReadFrom2(string input1, string input2) {
    int fd = WriteFileDescriptor2(input1, input2);
    if (fd < 0) {
      FAIL() << "Unable to create a pipe!";
    } else {
      string result;
      bool success = blaze_util::ReadFrom(
          [fd](void* buf, int size) { return read(fd, buf, size); }, &result);
      close(fd);
      if (!success) {
        perror("ReadFrom");
        FAIL() << "Unable to read file descriptor!";
      } else {
        ASSERT_EQ(input1 + input2, result);
      }
    }
  }

  static void AssertReadFrom(string input) { AssertReadFrom2(input, ""); }

  static void AssertReadJvmVersion(string expected, string input) {
    ASSERT_EQ(expected, ReadJvmVersion(input));
  }

  void ReadFromTest() const {
    AssertReadFrom(
        "DummyJDK Blabla\n"
        "More DummyJDK Blabla\n");
    AssertReadFrom(
        "dummyjdk version \"1.42.qual\"\n"
        "DummyJDK Blabla\n"
        "More DummyJDK Blabla\n");
    AssertReadFrom2("first_line\n", "second line version \"1.4.2_0\"\n");
  }

  void ReadJvmVersionTest() const {
    AssertReadJvmVersion("1.42", "dummyjdk version \"1.42\"\n"
                         "DummyJDK Blabla\n"
                         "More DummyJDK Blabla\n");
    AssertReadJvmVersion("1.42.qual", "dummyjdk version \"1.42.qual\"\n"
                         "DummyJDK Blabla\n"
                         "More DummyJDK Blabla\n");
    AssertReadJvmVersion("1.42.qualifie", "dummyjdk version \"1.42.qualifie");
    AssertReadJvmVersion("", "dummyjdk version ");
    AssertReadJvmVersion("1.4.2_0",
                          "first_line\nsecond line version \"1.4.2_0\"\n");
  }

  void CheckJavaVersionIsAtLeastTest() const {
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", ""));
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", "0"));
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", "1"));
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", "1.7"));
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", "1.7.0"));
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", "1.0"));
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", "1.6"));
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.42", "1"));
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.42", "1.7"));
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.42", "1.11"));
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.42.42", "1.11"));
    ASSERT_TRUE(CheckJavaVersionIsAtLeast("1.42.42", "1.11.11"));

    ASSERT_FALSE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", "42"));
    ASSERT_FALSE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", "2"));
    ASSERT_FALSE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", "1.8"));
    ASSERT_FALSE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", "1.7.1"));
    ASSERT_FALSE(CheckJavaVersionIsAtLeast("1.7.0-ver-specifier-42", "1.42"));
    ASSERT_FALSE(CheckJavaVersionIsAtLeast("1.42", "2"));
    ASSERT_FALSE(CheckJavaVersionIsAtLeast("1.42", "1.69"));
    ASSERT_FALSE(CheckJavaVersionIsAtLeast("1.42", "1.42.1"));
    ASSERT_FALSE(CheckJavaVersionIsAtLeast("1.42.42", "1.42.43"));
    ASSERT_FALSE(CheckJavaVersionIsAtLeast("1.42.42.0", "1.42.42.1"));
  }
};

TEST_F(BlazeUtilTest, CheckJavaVersionIsAtLeast) {
  CheckJavaVersionIsAtLeastTest();
}

TEST_F(BlazeUtilTest, ReadFrom) { ReadFromTest(); }

TEST_F(BlazeUtilTest, ReadJvmVersion) {
  ReadJvmVersionTest();
}

TEST_F(BlazeUtilTest, TestSearchNullaryEmptyCase) {
  ASSERT_FALSE(SearchNullaryOption({}, "--flag"));
}

TEST_F(BlazeUtilTest, TestSearchUnaryEmptyCase) {
  ASSERT_STREQ(nullptr, SearchUnaryOption({}, "--flag"));
}

TEST_F(BlazeUtilTest, TestSearchNullaryForEmpty) {
  ASSERT_FALSE(SearchNullaryOption({"bazel", "build", ":target"}, ""));
}

TEST_F(BlazeUtilTest, TestSearchNullaryForFlagNotPresent) {
  ASSERT_FALSE(SearchNullaryOption({"bazel", "build", ":target"},
                                   "--flag"));
}

TEST_F(BlazeUtilTest, TestSearchNullaryStartupOption) {
  ASSERT_TRUE(SearchNullaryOption({"bazel", "--flag", "build", ":target"},
                                  "--flag"));
}

TEST_F(BlazeUtilTest, TestSearchNullaryStartupOptionWithEquals) {
  ASSERT_DEATH(SearchNullaryOption(
      {"bazel", "--flag=value", "build", ":target"}, "--flag"),
              "In argument '--flag=value': option "
              "'--flag' does not take a value");
}

TEST_F(BlazeUtilTest, TestSearchNullaryCommandOption) {
  ASSERT_TRUE(SearchNullaryOption({"bazel", "build", ":target", "--flag"},
                                  "--flag"));
}

TEST_F(BlazeUtilTest, TestSearchUnaryForEmpty) {
  ASSERT_STREQ(nullptr, SearchUnaryOption({"bazel", "build", ":target"}, ""));
}

TEST_F(BlazeUtilTest, TestSearchUnaryFlagNotPresent) {
  ASSERT_STREQ(nullptr,
               SearchUnaryOption({"bazel", "build", ":target"}, "--flag"));
}

TEST_F(BlazeUtilTest, TestSearchUnaryStartupOptionWithEquals) {
  ASSERT_STREQ("value",
               SearchUnaryOption({"bazel", "--flag=value", "build", ":target"},
                                 "--flag"));
}

TEST_F(BlazeUtilTest, TestSearchUnaryStartupOptionWithoutEquals) {
  ASSERT_STREQ("value",
               SearchUnaryOption(
                   {"bazel", "--flag", "value", "build", ":target"}, "--flag"));
}

TEST_F(BlazeUtilTest, TestSearchUnaryCommandOptionWithEquals) {
  ASSERT_STREQ("value",
               SearchUnaryOption(
                   {"bazel", "build", ":target", "--flag", "value"}, "--flag"));
}

TEST_F(BlazeUtilTest, TestSearchUnaryCommandOptionWithoutEquals) {
  ASSERT_STREQ("value",
               SearchUnaryOption(
                   {"bazel", "build", ":target", "--flag=value"}, "--flag"));
}

}  // namespace blaze
