// 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 "base/test/scoped_task_environment.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.
    base::test::ScopedTaskEnvironment task_env_;
    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>();
    }
    DLOG(INFO) << "[Temporary debugging] javascript engine for parser exiting";
  }

  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
