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

#ifndef GARNET_BIN_SYSMGR_CONFIG_H_
#define GARNET_BIN_SYSMGR_CONFIG_H_

#include <string>
#include <unordered_map>
#include <utility>

#include <fuchsia/sys/cpp/fidl.h>
#include "src/lib/fxl/macros.h"
#include "lib/json/json_parser.h"
#include "rapidjson/document.h"

namespace sysmgr {

// Parses configuration files.  See README.md for format.
// TODO(jeffbrown): Support chaining multiple configuration files together
// via imports.
class Config {
 public:
  using ServiceMap =
      std::unordered_map<std::string, fuchsia::sys::LaunchInfoPtr>;
  using StartupServices = std::vector<std::string>;
  using UpdateDependencies = std::vector<std::string>;
  using OptionalServices = std::vector<std::string>;
  using AppVector = std::vector<fuchsia::sys::LaunchInfoPtr>;

  Config() = default;
  Config(Config&&) = default;
  Config& operator=(Config&&) = default;

  // Initializes the Config from a config directory, merging its files together.
  // Returns false if there were any errors.
  bool ParseFromDirectory(const std::string& dir);

  // Initializes the Config from a JSON string. |pseudo_file| is used as the
  // 'file' in the error string.
  bool ParseFromString(const std::string& data, const std::string& pseudo_file);

  bool HasError() const;
  std::string error_str() const;

  ServiceMap TakeServices() { return std::move(services_); }

  StartupServices TakeStartupServices() {
    return std::move(startup_services_);
  }

  UpdateDependencies TakeUpdateDependencies() {
    return std::move(update_dependencies_);
  }

  OptionalServices TakeOptionalServices() {
    return std::move(optional_services_);
  }

  AppVector TakeApps() { return std::move(apps_); }

 private:
  void ParseDocument(rapidjson::Document document);
  bool ParseServiceMap(const rapidjson::Document& document,
                       const std::string& key, Config::ServiceMap* services);
  void ReadJsonStringArray(
      const rapidjson::Document& document, const char* member,
      std::vector<std::string>* out);
  fuchsia::sys::LaunchInfoPtr GetLaunchInfo(
      const rapidjson::Document::ValueType& value, const std::string& name);

  ServiceMap services_;
  StartupServices startup_services_;
  UpdateDependencies update_dependencies_;
  OptionalServices optional_services_;
  AppVector apps_;
  json::JSONParser json_parser_;

  FXL_DISALLOW_COPY_AND_ASSIGN(Config);
};

}  // namespace sysmgr

#endif  // GARNET_BIN_SYSMGR_CONFIG_H_
