// Copyright 2015 The Cobalt 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 "cobalt/layout_tests/web_platform_test_parser.h"

#include <map>
#include <memory>
#include <utility>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/optional.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "cobalt/base/cobalt_paths.h"
#include "cobalt/layout_tests/test_utils.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/script/source_code.h"

namespace cobalt {
namespace layout_tests {

namespace {

std::string ExpectationToString(WebPlatformTestInfo::State state) {
  switch (state) {
    case WebPlatformTestInfo::kPass:
      return "PASS";
    case WebPlatformTestInfo::kFail:
      return "FAIL";
    case WebPlatformTestInfo::kDisable:
      return "DISABLE";
  }
  NOTREACHED();
  return "FAIL";
}

WebPlatformTestInfo::State StringToExpectation(
    const std::string& lower_case_string) {
  if (base::LowerCaseEqualsASCII(lower_case_string, "pass")) {
    return WebPlatformTestInfo::kPass;
  } else if (base::LowerCaseEqualsASCII(lower_case_string, "fail")) {
    return WebPlatformTestInfo::kFail;
  } else if (base::LowerCaseEqualsASCII(lower_case_string, "disable")) {
    return WebPlatformTestInfo::kDisable;
  } else {
    NOTREACHED() << "Invalid test expectation " << lower_case_string;
    return WebPlatformTestInfo::kFail;
  }
}

base::Optional<WebPlatformTestInfo> ParseWebPlatformTestCaseLine(
    const std::string& line_string) {
  std::vector<std::string> test_case_tokens = base::SplitString(
      line_string, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  if (test_case_tokens.size() < 2) {
    DLOG(WARNING) << "Failed to parse: " << line_string;
    return base::nullopt;
  }

  for (size_t i = 0; i < test_case_tokens.size(); ++i) {
    TrimWhitespaceASCII(test_case_tokens[i], base::TRIM_ALL,
                        &test_case_tokens[i]);
  }

  std::string test_expect = base::ToLowerASCII(test_case_tokens[1]);
  WebPlatformTestInfo::State expectation = StringToExpectation(test_expect);
  if (expectation == WebPlatformTestInfo::kDisable) {
    return base::nullopt;
  } else {
    WebPlatformTestInfo test_info;
    test_info.url = test_case_tokens[0];
    test_info.expectation = expectation;
    for (size_t i = 2; i < test_case_tokens.size(); ++i) {
      test_info.exceptions.insert(test_case_tokens[i]);
    }
    return test_info;
  }
}

}  // namespace

std::ostream& operator<<(std::ostream& out,
                         const WebPlatformTestInfo& test_info) {
  return out << test_info.url
             << " Expected: " << ExpectationToString(test_info.expectation);
}

std::vector<WebPlatformTestInfo> EnumerateWebPlatformTests(
    const std::string& top_level, const char* precondition) {
  if (precondition) {
    // Evaluate the javascript precondition. Enumerate the web platform tests
    // only if the precondition is true.
    std::unique_ptr<script::JavaScriptEngine> engine =
        script::JavaScriptEngine::CreateEngine();
    scoped_refptr<script::GlobalEnvironment> global_environment =
        engine->CreateGlobalEnvironment();
    global_environment->CreateGlobalObject();

    std::string result;
    bool success = global_environment->EvaluateScript(
        script::SourceCode::CreateSourceCode(
            precondition, base::SourceLocation(__FILE__, __LINE__, 1)),
        &result);

    if (!success) {
      DLOG(ERROR) << "Failed to evaluate precondition: "
                  << "\"" << precondition << "\"";
      // Continue to enumerate tests like normal.
    } else if (result != "true") {
      DLOG(WARNING) << "Skipping Web Platform Tests for "
                    << "\"" << top_level << "\"";
      return std::vector<WebPlatformTestInfo>();
    }
  }

  base::FilePath test_dir(GetTestInputRootDirectory()
                              .Append("web-platform-tests")
                              .Append(top_level));
  base::FilePath tests_list_file(
      test_dir.Append(FILE_PATH_LITERAL("web_platform_tests.txt")));

  std::string test_list;
  if (!base::ReadFileToString(tests_list_file, &test_list)) {
    DLOG(ERROR) << "Could not open '" << tests_list_file.value() << "'.";
    return std::vector<WebPlatformTestInfo>();
  } else {
    // base::SplitString the file contents into lines, and then read each line
    // one by one as the name of the test file.
    std::vector<std::string> line_tokens = base::SplitString(
        test_list, "\n\r", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

    const char kCommentChar = '#';

    typedef std::map<std::string, WebPlatformTestInfo> TestInfoMap;
    TestInfoMap all_test_infos;
    for (std::vector<std::string>::iterator iter = line_tokens.begin();
         iter != line_tokens.end(); ++iter) {
      std::string trimmed_line;
      TrimWhitespaceASCII(*iter, base::TRIM_ALL, &trimmed_line);

      // Skip commented-out lines.
      if (trimmed_line.size() > 0 && trimmed_line[0] == kCommentChar) {
        continue;
      }

      base::Optional<WebPlatformTestInfo> parsed_test_info =
          ParseWebPlatformTestCaseLine(trimmed_line);
      if (parsed_test_info) {
        WebPlatformTestInfo& test_info = *parsed_test_info;
        test_info.url = top_level + "/" + test_info.url;
        std::pair<TestInfoMap::iterator, bool> ret =
            all_test_infos.insert(std::make_pair(test_info.url, test_info));
        // If it's the same url, merge the exceptions into the original one.
        if (ret.second == false) {
          // Ensure that neither expectation is set to disable, and that the
          // expectations are different.
          DCHECK_NE(ret.first->second.expectation,
                    WebPlatformTestInfo::kDisable);
          DCHECK_NE(test_info.expectation, WebPlatformTestInfo::kDisable);
          DCHECK_NE(ret.first->second.expectation, test_info.expectation);

          // There should be at least one test in the list of exceptions for
          // the new one. Append these to the existing exceptions list.
          DCHECK_GT(test_info.exceptions.size(), size_t(0));
          ret.first->second.exceptions.insert(test_info.exceptions.begin(),
                                              test_info.exceptions.end());
        }
      }
    }

    std::vector<WebPlatformTestInfo> test_info_list;
    for (TestInfoMap::iterator it = all_test_infos.begin();
         it != all_test_infos.end(); ++it) {
      test_info_list.push_back(it->second);
    }
    return test_info_list;
  }
}

}  // namespace layout_tests
}  // namespace cobalt
