// Copyright 2019 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 <memory>

#include "deps_log.h"
#include "graph.h"
#include "missing_deps.h"
#include "state.h"
#include "test.h"

const char kTestDepsLogFilename[] = "MissingDepTest-tempdepslog";

class MissingDependencyTestDelegate : public MissingDependencyScannerDelegate {
  void OnMissingDep(Node* node, const std::string& path,
                    const Rule& generator) {}
};

struct MissingDependencyScannerTest : public testing::Test {
  MissingDependencyScannerTest()
      : generator_rule_("generator_rule"), compile_rule_("compile_rule"),
        scanner_(&delegate_, &deps_log_, &state_, &filesystem_) {
    std::string err;
    deps_log_.OpenForWrite(kTestDepsLogFilename, &err);
    ASSERT_EQ("", err);
  }

  MissingDependencyScanner& scanner() { return scanner_; }

  void RecordDepsLogDep(const std::string& from, const std::string& to) {
    Node* node_deps[] = { state_.LookupNode(to) };
    deps_log_.RecordDeps(state_.LookupNode(from), 0, 1, node_deps);
  }

  void ProcessAllNodes() {
    std::string err;
    std::vector<Node*> nodes = state_.RootNodes(&err);
    EXPECT_EQ("", err);
    for (std::vector<Node*>::iterator it = nodes.begin(); it != nodes.end();
         ++it) {
      scanner().ProcessNode(*it);
    }
  }

  void CreateInitialState() {
    EvalString deps_type;
    deps_type.AddText("gcc");
    compile_rule_.AddBinding("deps", deps_type);
    generator_rule_.AddBinding("deps", deps_type);
    Edge* header_edge = state_.AddEdge(&generator_rule_);
    state_.AddOut(header_edge, "generated_header", 0);
    Edge* compile_edge = state_.AddEdge(&compile_rule_);
    state_.AddOut(compile_edge, "compiled_object", 0);
  }

  void CreateGraphDependencyBetween(const char* from, const char* to) {
    Node* from_node = state_.LookupNode(from);
    Edge* from_edge = from_node->in_edge();
    state_.AddIn(from_edge, to, 0);
  }

  void AssertMissingDependencyBetween(const char* flaky, const char* generated,
                                      Rule* rule) {
    Node* flaky_node = state_.LookupNode(flaky);
    ASSERT_EQ(1u, scanner().nodes_missing_deps_.count(flaky_node));
    Node* generated_node = state_.LookupNode(generated);
    ASSERT_EQ(1u, scanner().generated_nodes_.count(generated_node));
    ASSERT_EQ(1u, scanner().generator_rules_.count(rule));
  }

  MissingDependencyTestDelegate delegate_;
  Rule generator_rule_;
  Rule compile_rule_;
  DepsLog deps_log_;
  State state_;
  VirtualFileSystem filesystem_;
  MissingDependencyScanner scanner_;
};

TEST_F(MissingDependencyScannerTest, EmptyGraph) {
  ProcessAllNodes();
  ASSERT_FALSE(scanner().HadMissingDeps());
}

TEST_F(MissingDependencyScannerTest, NoMissingDep) {
  CreateInitialState();
  ProcessAllNodes();
  ASSERT_FALSE(scanner().HadMissingDeps());
}

TEST_F(MissingDependencyScannerTest, MissingDepPresent) {
  CreateInitialState();
  // compiled_object uses generated_header, without a proper dependency
  RecordDepsLogDep("compiled_object", "generated_header");
  ProcessAllNodes();
  ASSERT_TRUE(scanner().HadMissingDeps());
  ASSERT_EQ(1u, scanner().nodes_missing_deps_.size());
  ASSERT_EQ(1u, scanner().missing_dep_path_count_);
  AssertMissingDependencyBetween("compiled_object", "generated_header",
                                 &generator_rule_);
}

TEST_F(MissingDependencyScannerTest, MissingDepFixedDirect) {
  CreateInitialState();
  // Adding the direct dependency fixes the missing dep
  CreateGraphDependencyBetween("compiled_object", "generated_header");
  RecordDepsLogDep("compiled_object", "generated_header");
  ProcessAllNodes();
  ASSERT_FALSE(scanner().HadMissingDeps());
}

TEST_F(MissingDependencyScannerTest, MissingDepFixedIndirect) {
  CreateInitialState();
  // Adding an indirect dependency also fixes the issue
  Edge* intermediate_edge = state_.AddEdge(&generator_rule_);
  state_.AddOut(intermediate_edge, "intermediate", 0);
  CreateGraphDependencyBetween("compiled_object", "intermediate");
  CreateGraphDependencyBetween("intermediate", "generated_header");
  RecordDepsLogDep("compiled_object", "generated_header");
  ProcessAllNodes();
  ASSERT_FALSE(scanner().HadMissingDeps());
}

TEST_F(MissingDependencyScannerTest, CyclicMissingDep) {
  CreateInitialState();
  RecordDepsLogDep("generated_header", "compiled_object");
  RecordDepsLogDep("compiled_object", "generated_header");
  // In case of a cycle, both paths are reported (and there is
  // no way to fix the issue by adding deps).
  ProcessAllNodes();
  ASSERT_TRUE(scanner().HadMissingDeps());
  ASSERT_EQ(2u, scanner().nodes_missing_deps_.size());
  ASSERT_EQ(2u, scanner().missing_dep_path_count_);
  AssertMissingDependencyBetween("compiled_object", "generated_header",
                                 &generator_rule_);
  AssertMissingDependencyBetween("generated_header", "compiled_object",
                                 &compile_rule_);
}

TEST_F(MissingDependencyScannerTest, CycleInGraph) {
  CreateInitialState();
  CreateGraphDependencyBetween("compiled_object", "generated_header");
  CreateGraphDependencyBetween("generated_header", "compiled_object");
  // The missing-deps tool doesn't deal with cycles in the graph, beacuse
  // there will be an error loading the graph before we get to the tool.
  // This test is to illustrate that.
  std::string err;
  std::vector<Node*> nodes = state_.RootNodes(&err);
  ASSERT_NE("", err);
}

