// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/arc/arc_features_parser.h"

#include <memory>

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/values.h"

namespace arc {

namespace {

constexpr const base::FilePath::CharType kArcFeaturesJsonFile[] =
    FILE_PATH_LITERAL("/etc/arc/features.json");

base::Optional<ArcFeatures> ParseFeaturesJson(base::StringPiece input_json) {
  ArcFeatures arc_features;

  int error_code;
  std::string error_msg;
  std::unique_ptr<base::Value> json_value =
      base::JSONReader::ReadAndReturnErrorDeprecated(
          input_json, base::JSON_PARSE_RFC, &error_code, &error_msg);
  if (!json_value || !json_value->is_dict()) {
    LOG(ERROR) << "Error parsing feature JSON: " << error_msg;
    return base::nullopt;
  }

  // Parse each item under features.
  const base::Value* feature_list =
      json_value->FindKeyOfType("features", base::Value::Type::LIST);
  if (!feature_list) {
    LOG(ERROR) << "No feature list in JSON.";
    return base::nullopt;
  }
  for (auto& feature_item : feature_list->GetList()) {
    const base::Value* feature_name =
        feature_item.FindKeyOfType("name", base::Value::Type::STRING);
    const base::Value* feature_version =
        feature_item.FindKeyOfType("version", base::Value::Type::INTEGER);
    if (!feature_name || feature_name->GetString().empty()) {
      LOG(ERROR) << "Missing name in the feature.";
      return base::nullopt;
    }
    if (!feature_version) {
      LOG(ERROR) << "Missing version in the feature.";
      return base::nullopt;
    }
    arc_features.feature_map.emplace(feature_name->GetString(),
                                     feature_version->GetInt());
  }

  // Parse each item under unavailable_features.
  const base::Value* unavailable_feature_list = json_value->FindKeyOfType(
      "unavailable_features", base::Value::Type::LIST);
  if (!unavailable_feature_list) {
    LOG(ERROR) << "No unavailable feature list in JSON.";
    return base::nullopt;
  }
  for (auto& feature_item : unavailable_feature_list->GetList()) {
    if (!feature_item.is_string()) {
      LOG(ERROR) << "Item in the unavailable feature list is not a string.";
      return base::nullopt;
    }

    if (feature_item.GetString().empty()) {
      LOG(ERROR) << "Missing name in the feature.";
      return base::nullopt;
    }
    arc_features.unavailable_features.emplace_back(feature_item.GetString());
  }

  // Parse each item under properties.
  const base::Value* properties =
      json_value->FindKeyOfType("properties", base::Value::Type::DICTIONARY);
  if (!properties) {
    LOG(ERROR) << "No properties in JSON.";
    return base::nullopt;
  }
  for (const auto& item : properties->DictItems()) {
    if (!item.second.is_string()) {
      LOG(ERROR) << "Item in the properties mapping is not a string.";
      return base::nullopt;
    }

    arc_features.build_props.emplace(item.first, item.second.GetString());
  }

  // Parse the Play Store version
  const base::Value* play_version = json_value->FindKeyOfType(
      "play_store_version", base::Value::Type::STRING);
  if (!play_version) {
    LOG(ERROR) << "No Play Store version in JSON.";
    return base::nullopt;
  }
  arc_features.play_store_version = play_version->GetString();

  return arc_features;
}

base::Optional<ArcFeatures> ReadOnFileThread(const base::FilePath& file_path) {
  DCHECK(!file_path.empty());
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  std::string input_json;
  {
    base::ScopedBlockingCall scoped_blocking_call(
        base::BlockingType::MAY_BLOCK);
    if (!base::ReadFileToString(file_path, &input_json)) {
      PLOG(ERROR) << "Cannot read file " << file_path.value()
                  << " into string.";
      return base::nullopt;
    }
  }

  if (input_json.empty()) {
    LOG(ERROR) << "Input JSON is empty in file " << file_path.value();
    return base::nullopt;
  }

  return ParseFeaturesJson(input_json);
}

}  // namespace

ArcFeatures::ArcFeatures() = default;
ArcFeatures::ArcFeatures(ArcFeatures&& other) = default;
ArcFeatures::~ArcFeatures() = default;
ArcFeatures& ArcFeatures::operator=(ArcFeatures&& other) = default;

void ArcFeaturesParser::GetArcFeatures(
    base::OnceCallback<void(base::Optional<ArcFeatures>)> callback) {
  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
      base::BindOnce(&ReadOnFileThread, base::FilePath(kArcFeaturesJsonFile)),
      std::move(callback));
}

base::Optional<ArcFeatures> ArcFeaturesParser::ParseFeaturesJsonForTesting(
    base::StringPiece input_json) {
  return ParseFeaturesJson(input_json);
}

}  // namespace arc
