// Copyright 2015 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 <algorithm>

#include "mock_iptables.h"

namespace firewalld {

MockIpTables::~MockIpTables() {
  PlugAllHoles();
}

int MockIpTables::SetExecvNonRootFailCriterion(
    const std::vector<std::string>& keywords, bool repeat,
    bool omit_failure) {
  match_criteria_.push_back(Criterion{keywords, repeat, omit_failure, 0});
  return match_criteria_.size() - 1;
}

int MockIpTables::GetExecvNonRootCriterionMatchCount(int id) {
  if (id < 0 || id >= (int) match_criteria_.size())
    return -1;
  return match_criteria_[id].match_count;
}

bool MockIpTables::MatchAndUpdate(const std::vector<std::string>& argv) {
  for (auto& criterion : match_criteria_) {
    bool match = true;
    // Empty criterion is a catch all -- fail on any ExecvNonRoot.
    for (const std::string& keyword : criterion.keywords) {
      match = match &&
        (std::find(argv.begin(), argv.end(), keyword) != argv.end());
    }
    if (match) {
      criterion.match_count++;
      if (!criterion.repeat) {
        match_criteria_.erase(std::remove(match_criteria_.begin(),
                                          match_criteria_.end(),
                                          criterion),
                              match_criteria_.end());
      }
      // If not negating, treat as fail criterion,
      // otherwise ignore (return false).
      return !criterion.omit_failure;
    }
  }
  return false;
}

int MockIpTables::ExecvNonRoot(
    const std::vector<std::string>& argv, uint64_t capmask) {
  if (MatchAndUpdate(argv))
    return 1;
  commands_.push_back(argv);
  return 0;
}

std::vector<std::string> MockIpTables::GetInverseCommand(
    const std::vector<std::string>& argv) {
  std::vector<std::string> inverse;
  bool isIpTablesCommand = (argv.size() > 0) && argv[0] == kIpTablesPath;
  bool isIpCommand = (argv.size() > 0) && argv[0] == kIpPath;
  for (const auto& arg : argv) {
    if (arg == "-A" && isIpTablesCommand)
      inverse.push_back("-D");
    else if (arg == "-D" && isIpTablesCommand)
      inverse.push_back("-A");
    else if (arg == "add" && isIpCommand)
      inverse.push_back("delete");
    else if (arg == "delete" && isIpCommand)
      inverse.push_back("add");
    else
      inverse.push_back(arg);
  }
  return inverse;
}

// This check does not enforce ordering. It only checks
// that for each command that adds a rule/mark with
// ip/iptables, there is a later match command that
// deletes that same rule/mark.
bool MockIpTables::CheckCommandsUndone() {
  for (std::vector<std::vector<std::string>>::iterator it = commands_.begin();
       it != commands_.end(); it++) {
    // For each command that adds a rule, check that its inverse
    // exists later in the log of commands.
    if ((std::find(it->begin(), it->end(), "-A") != it->end()) ||
        (std::find(it->begin(), it->end(), "add") != it->end())) {
      bool found = false;
      std::vector<std::string> inverse = GetInverseCommand(*it);
      // If GetInverseCommand returns the same command, then it was
      // not an ip/iptables command that added/removed a rule/mark.
      if (std::equal(it->begin(), it->end(), inverse.begin()))
        continue;
      for (auto it_next = it + 1; it_next != commands_.end(); it_next++) {
        if (*it_next == inverse) {
          found = true;
          break;
        }
      }
      if (!found)
        return false;
    }
  }
  return true;
}

}  // namespace firewalld
