// Copyright 2016 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/payments/core/payment_details_validation.h"

#include <set>
#include <vector>

#include "components/payments/core/payment_details.h"
#include "components/payments/core/payments_validators.h"

namespace payments {
namespace {

// Validates ShippingOption or PaymentItem, which happen to have identical
// fields, except for "id", which is present only in ShippingOption.
template <typename T>
bool ValidateShippingOptionOrPaymentItem(const T& item,
                                         const PaymentItem& total,
                                         std::string* error_message) {
  if (!item.amount) {
    *error_message = "Amount required";
    return false;
  }

  if (item.amount->currency.empty()) {
    *error_message = "Currency code required";
    return false;
  }

  if (item.amount->value.empty()) {
    *error_message = "Currency value required";
    return false;
  }

  if (!payments::PaymentsValidators::IsValidCurrencyCodeFormat(
          item.amount->currency, error_message)) {
    return false;
  }

  if (!payments::PaymentsValidators::IsValidAmountFormat(item.amount->value,
                                                         error_message)) {
    return false;
  }
  return true;
}

bool ValidateDisplayItems(const std::vector<PaymentItem>& items,
                          const PaymentItem& total,
                          std::string* error_message) {
  for (const auto& item : items) {
    if (!ValidateShippingOptionOrPaymentItem(item, total, error_message))
      return false;
  }
  return true;
}

bool ValidateShippingOptions(const std::vector<PaymentShippingOption>& options,
                             const PaymentItem& total,
                             std::string* error_message) {
  std::set<std::string> uniqueIds;
  for (const auto& option : options) {
    if (option.id.empty()) {
      *error_message = "ShippingOption id required";
      return false;
    }

    if (uniqueIds.find(option.id) != uniqueIds.end()) {
      *error_message = "Duplicate shipping option identifiers are not allowed";
      return false;
    }
    uniqueIds.insert(option.id);

    if (!ValidateShippingOptionOrPaymentItem(option, total, error_message))
      return false;
  }
  return true;
}

bool ValidatePaymentDetailsModifiers(
    const std::vector<PaymentDetailsModifier>& modifiers,
    const PaymentItem& total,
    std::string* error_message) {
  if (modifiers.empty()) {
    *error_message = "Must specify at least one payment details modifier";
    return false;
  }

  for (const auto& modifier : modifiers) {
    if (modifier.method_data.supported_method.empty()) {
      *error_message = "Must specify payment method identifier";
      return false;
    }

    if (modifier.total) {
      if (!ValidateShippingOptionOrPaymentItem(*modifier.total, total,
                                               error_message))
        return false;

      if (modifier.total->amount->value[0] == '-') {
        *error_message = "Total amount value should be non-negative";
        return false;
      }
    }

    if (modifier.additional_display_items.size()) {
      if (!ValidateDisplayItems(modifier.additional_display_items, total,
                                error_message)) {
        return false;
      }
    }
  }
  return true;
}

}  // namespace

bool ValidatePaymentDetails(const PaymentDetails& details,
                            std::string* error_message) {
  if (details.total) {
    if (!ValidateShippingOptionOrPaymentItem(*details.total, *details.total,
                                             error_message)) {
      return false;
    }

    if (details.total->amount->value[0] == '-') {
      *error_message = "Total amount value should be non-negative";
      return false;
    }
  }

  if (details.display_items.size()) {
    if (!ValidateDisplayItems(details.display_items, *details.total,
                              error_message))
      return false;
  }

  if (details.shipping_options.size()) {
    if (!ValidateShippingOptions(details.shipping_options, *details.total,
                                 error_message))
      return false;
  }

  if (details.modifiers.size()) {
    if (!ValidatePaymentDetailsModifiers(details.modifiers, *details.total,
                                         error_message))
      return false;
  }
  if (!PaymentsValidators::IsValidErrorMsgFormat(details.error, error_message))
    return false;
  return true;
}

}  // namespace payments
