// Copyright 2011 Google Inc. 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 "build_log.h"

#include "util.h"
#include "test.h"

#ifdef _WIN32
#include <fcntl.h>
#include <share.h>
#endif

#ifdef linux
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif

const char kTestFilename[] = "BuildLogTest-tempfile";

struct BuildLogTest : public StateTestWithBuiltinRules {
  virtual void SetUp() {
  }
  virtual void TearDown() {
    unlink(kTestFilename);
  }
};

TEST_F(BuildLogTest, WriteRead) {
  AssertParse(&state_,
"build out: cat mid\n"
"build mid: cat in\n");

  BuildLog log1;
  string err;
  EXPECT_TRUE(log1.OpenForWrite(kTestFilename, &err));
  ASSERT_EQ("", err);
  log1.RecordCommand(state_.edges_[0], 15, 18);
  log1.RecordCommand(state_.edges_[1], 20, 25);
  log1.Close();

  BuildLog log2;
  EXPECT_TRUE(log2.Load(kTestFilename, &err));
  ASSERT_EQ("", err);

  ASSERT_EQ(2u, log1.log().size());
  ASSERT_EQ(2u, log2.log().size());
  BuildLog::LogEntry* e1 = log1.LookupByOutput("out");
  ASSERT_TRUE(e1);
  BuildLog::LogEntry* e2 = log2.LookupByOutput("out");
  ASSERT_TRUE(e2);
  ASSERT_TRUE(*e1 == *e2);
  ASSERT_EQ(15, e1->start_time);
  ASSERT_EQ("out", e1->output);
}

TEST_F(BuildLogTest, FirstWriteAddsSignature) {
  const char kExpectedVersion[] = "# ninja log vX\n";
  const size_t kVersionPos = strlen(kExpectedVersion) - 2;  // Points at 'X'.

  BuildLog log;
  string contents, err;

  EXPECT_TRUE(log.OpenForWrite(kTestFilename, &err));
  ASSERT_EQ("", err);
  log.Close();

  ASSERT_EQ(0, ReadFile(kTestFilename, &contents, &err));
  ASSERT_EQ("", err);
  if (contents.size() >= kVersionPos)
    contents[kVersionPos] = 'X';
  EXPECT_EQ(kExpectedVersion, contents);

  // Opening the file anew shouldn't add a second version string.
  EXPECT_TRUE(log.OpenForWrite(kTestFilename, &err));
  ASSERT_EQ("", err);
  log.Close();

  contents.clear();
  ASSERT_EQ(0, ReadFile(kTestFilename, &contents, &err));
  ASSERT_EQ("", err);
  if (contents.size() >= kVersionPos)
    contents[kVersionPos] = 'X';
  EXPECT_EQ(kExpectedVersion, contents);
}

TEST_F(BuildLogTest, DoubleEntry) {
  FILE* f = fopen(kTestFilename, "wb");
  fprintf(f, "# ninja log v4\n");
  fprintf(f, "0\t1\t2\tout\tcommand abc\n");
  fprintf(f, "3\t4\t5\tout\tcommand def\n");
  fclose(f);

  string err;
  BuildLog log;
  EXPECT_TRUE(log.Load(kTestFilename, &err));
  ASSERT_EQ("", err);

  BuildLog::LogEntry* e = log.LookupByOutput("out");
  ASSERT_TRUE(e);
  ASSERT_NO_FATAL_FAILURE(AssertHash("command def", e->command_hash));
}

TEST_F(BuildLogTest, Truncate) {
  AssertParse(&state_,
"build out: cat mid\n"
"build mid: cat in\n");

  BuildLog log1;
  string err;
  EXPECT_TRUE(log1.OpenForWrite(kTestFilename, &err));
  ASSERT_EQ("", err);
  log1.RecordCommand(state_.edges_[0], 15, 18);
  log1.RecordCommand(state_.edges_[1], 20, 25);
  log1.Close();

  struct stat statbuf;
  ASSERT_EQ(0, stat(kTestFilename, &statbuf));
  ASSERT_GT(statbuf.st_size, 0);

  // For all possible truncations of the input file, assert that we don't
  // crash or report an error when parsing.
  for (off_t size = statbuf.st_size; size > 0; --size) {
#ifndef _WIN32
    ASSERT_EQ(0, truncate(kTestFilename, size));
#else
    int fh;
    fh = _sopen(kTestFilename, _O_RDWR | _O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE);
    ASSERT_EQ(0, _chsize(fh, size));
    _close(fh);
#endif

    BuildLog log2;
    EXPECT_TRUE(log2.Load(kTestFilename, &err));
    ASSERT_EQ("", err);
  }
}

TEST_F(BuildLogTest, ObsoleteOldVersion) {
  FILE* f = fopen(kTestFilename, "wb");
  fprintf(f, "# ninja log v3\n");
  fprintf(f, "123 456 0 out command\n");
  fclose(f);

  string err;
  BuildLog log;
  EXPECT_FALSE(log.Load(kTestFilename, &err));
  ASSERT_NE(err.find("version"), string::npos);
}

TEST_F(BuildLogTest, SpacesInOutputV4) {
  FILE* f = fopen(kTestFilename, "wb");
  fprintf(f, "# ninja log v4\n");
  fprintf(f, "123\t456\t456\tout with space\tcommand\n");
  fclose(f);

  string err;
  BuildLog log;
  EXPECT_TRUE(log.Load(kTestFilename, &err));
  ASSERT_EQ("", err);

  BuildLog::LogEntry* e = log.LookupByOutput("out with space");
  ASSERT_TRUE(e);
  ASSERT_EQ(123, e->start_time);
  ASSERT_EQ(456, e->end_time);
  ASSERT_EQ(456, e->restat_mtime);
  ASSERT_NO_FATAL_FAILURE(AssertHash("command", e->command_hash));
}

TEST_F(BuildLogTest, DuplicateVersionHeader) {
  // Old versions of ninja accidentally wrote multiple version headers to the
  // build log on Windows. This shouldn't crash, and the second version header
  // should be ignored.
  FILE* f = fopen(kTestFilename, "wb");
  fprintf(f, "# ninja log v4\n");
  fprintf(f, "123\t456\t456\tout\tcommand\n");
  fprintf(f, "# ninja log v4\n");
  fprintf(f, "456\t789\t789\tout2\tcommand2\n");
  fclose(f);

  string err;
  BuildLog log;
  EXPECT_TRUE(log.Load(kTestFilename, &err));
  ASSERT_EQ("", err);

  BuildLog::LogEntry* e = log.LookupByOutput("out");
  ASSERT_TRUE(e);
  ASSERT_EQ(123, e->start_time);
  ASSERT_EQ(456, e->end_time);
  ASSERT_EQ(456, e->restat_mtime);
  ASSERT_NO_FATAL_FAILURE(AssertHash("command", e->command_hash));

  e = log.LookupByOutput("out2");
  ASSERT_TRUE(e);
  ASSERT_EQ(456, e->start_time);
  ASSERT_EQ(789, e->end_time);
  ASSERT_EQ(789, e->restat_mtime);
  ASSERT_NO_FATAL_FAILURE(AssertHash("command2", e->command_hash));
}

TEST_F(BuildLogTest, VeryLongInputLine) {
  // Ninja's build log buffer is currently 256kB. Lines longer than that are
  // silently ignored, but don't affect parsing of other lines.
  FILE* f = fopen(kTestFilename, "wb");
  fprintf(f, "# ninja log v4\n");
  fprintf(f, "123\t456\t456\tout\tcommand start");
  for (size_t i = 0; i < (512 << 10) / strlen(" more_command"); ++i)
    fputs(" more_command", f);
  fprintf(f, "\n");
  fprintf(f, "456\t789\t789\tout2\tcommand2\n");
  fclose(f);

  string err;
  BuildLog log;
  EXPECT_TRUE(log.Load(kTestFilename, &err));
  ASSERT_EQ("", err);

  BuildLog::LogEntry* e = log.LookupByOutput("out");
  ASSERT_EQ(NULL, e);

  e = log.LookupByOutput("out2");
  ASSERT_TRUE(e);
  ASSERT_EQ(456, e->start_time);
  ASSERT_EQ(789, e->end_time);
  ASSERT_EQ(789, e->restat_mtime);
  ASSERT_NO_FATAL_FAILURE(AssertHash("command2", e->command_hash));
}
