// Copyright (c) 2011 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 <stddef.h>
#include <cstdio>
#include <iostream>
#include <utility>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/json/json_file_value_serializer.h"
#include "base/logging.h"
#include "base/values.h"
#include "chromeos/network/onc/onc_signature.h"
#include "chromeos/network/onc/onc_validator.h"

// TODO Check why this file do not fail on default trybots
// http://crbug.com/543919

// Command line switches.
const char kSwitchErrorOnUnknownField[] = "error-on-unknown-field";
const char kSwitchErrorOnWrongRecommended[] = "error-on-wrong-recommended";
const char kSwitchErrorOnMissingField[] = "error-on-missing-field";
const char kSwitchManagedOnc[] = "managed-onc";
const char kSwitchUserPolicy[] = "user-policy";
const char kSwitchDevicePolicy[] = "device-policy";
const char kSwitchUserImport[] = "user-import";

const char* kSwitches[] = {
  kSwitchErrorOnUnknownField,
  kSwitchErrorOnWrongRecommended,
  kSwitchErrorOnMissingField,
  kSwitchManagedOnc,
  kSwitchUserPolicy,
  kSwitchDevicePolicy,
  kSwitchUserImport
};

// Return codes.
enum ReturnCode {
  kStatusValid = 0,
  kStatusWarnings = 1,
  kStatusInvalid = 2,
  kStatusJsonError = 3,
  kStatusArgumentError = 4,
};

const char kToplevelConfiguration[] = "ToplevelConfiguration";
const char kNetworkConfiguration[] = "NetworkConfiguration";
const char kCertificate[] = "Certificate";
const char* kTypes[] = {
  kToplevelConfiguration,
  kNetworkConfiguration,
  kCertificate
};

void PrintHelp() {
  fprintf(stderr,
          "Usage:\n"
          "  onc_validator [OPTION]... [TYPE] onc_file\n"
          "\n"
          "Valid TYPEs are:\n");
  for (size_t i = 0; i < arraysize(kTypes); ++i)
    fprintf(stderr, "  %s\n", kTypes[i]);

  fprintf(stderr,
          "\n"
          "Valid OPTIONs are:\n");
  for (size_t i = 0; i < arraysize(kSwitches); ++i)
    fprintf(stderr, "  --%s\n", kSwitches[i]);

  fprintf(stderr,
          "\n"
          "Exit status is one of:\n"
          "  %i  File is valid without warnings.\n"
          "  %i  File is valid with warnings,\n"
          "       i.e. there were errors which were degraded to warnings.\n"
          "  %i  File is invalid.\n"
          "  %i  File couldn't be read or is not a valid JSON dictionary.\n"
          "  %i  Some command line arguments are wrong.\n",
          kStatusValid,
          kStatusWarnings,
          kStatusInvalid,
          kStatusJsonError,
          kStatusArgumentError);
}

std::unique_ptr<base::DictionaryValue> ReadDictionary(
    const std::string& filename) {
  base::FilePath path(filename);
  JSONFileValueDeserializer deserializer(path);
  deserializer.set_allow_trailing_comma(true);

  std::string json_error;
  std::unique_ptr<base::Value> value =
      deserializer.Deserialize(NULL, &json_error);
  if (!value) {
    LOG(ERROR) << "Couldn't json-deserialize file '" << filename
               << "': " << json_error;
    return nullptr;
  }

  std::unique_ptr<base::DictionaryValue> dict =
      base::DictionaryValue::From(std::move(value));
  if (!dict) {
    LOG(ERROR) << "File '" << filename
               << "' does not contain a dictionary as expected, but type "
               << value->GetType();
  }

  return dict;
}

int main(int argc, const char* argv[]) {
  base::CommandLine::Init(argc, argv);

  const base::CommandLine& command_line =
      *base::CommandLine::ForCurrentProcess();
  base::CommandLine::StringVector args = command_line.GetArgs();
  if (args.size() != 2) {
    PrintHelp();
    return kStatusArgumentError;
  }

  std::unique_ptr<base::DictionaryValue> onc_object = ReadDictionary(args[1]);

  if (!onc_object)
    return kStatusJsonError;

  chromeos::onc::Validator validator(
      command_line.HasSwitch(kSwitchErrorOnUnknownField),
      command_line.HasSwitch(kSwitchErrorOnWrongRecommended),
      command_line.HasSwitch(kSwitchErrorOnMissingField),
      command_line.HasSwitch(kSwitchManagedOnc));

  if (command_line.HasSwitch(kSwitchUserPolicy))
    validator.SetOncSource(::onc::ONC_SOURCE_USER_POLICY);
  else if (command_line.HasSwitch(kSwitchDevicePolicy))
    validator.SetOncSource(::onc::ONC_SOURCE_DEVICE_POLICY);
  else if (command_line.HasSwitch(kSwitchUserImport))
    validator.SetOncSource(::onc::ONC_SOURCE_USER_IMPORT);

  std::string type_arg(args[0]);
  const chromeos::onc::OncValueSignature* signature = NULL;
  if (type_arg == kToplevelConfiguration) {
    signature = &chromeos::onc::kToplevelConfigurationSignature;
  } else if (type_arg == kNetworkConfiguration) {
    signature = &chromeos::onc::kNetworkConfigurationSignature;
  } else if (type_arg == kCertificate) {
    signature = &chromeos::onc::kCertificateSignature;
  } else {
    LOG(ERROR) << "Unknown ONC type '" << type_arg << "'";
    return kStatusArgumentError;
  }

  chromeos::onc::Validator::Result result;
  validator.ValidateAndRepairObject(signature, *onc_object, &result);

  switch (result) {
    case chromeos::onc::Validator::VALID:
      return kStatusValid;
    case chromeos::onc::Validator::VALID_WITH_WARNINGS:
      return kStatusWarnings;
    case chromeos::onc::Validator::INVALID:
      return kStatusInvalid;
    default:
      CHECK(false);
  }
}
