// Copyright (C) 2014 Google Inc.
//
// 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 "validation_task.h"

#include <libaddressinput/address_data.h>
#include <libaddressinput/address_field.h>
#include <libaddressinput/address_metadata.h>
#include <libaddressinput/address_problem.h>
#include <libaddressinput/address_validator.h>
#include <libaddressinput/callback.h>
#include <libaddressinput/supplier.h>

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <string>

#include <re2/re2.h>

#include "lookup_key.h"
#include "post_box_matchers.h"
#include "rule.h"
#include "util/re2ptr.h"
#include "util/size.h"

namespace i18n {
namespace addressinput {

ValidationTask::ValidationTask(const AddressData& address, bool allow_postal,
                               bool require_name, const FieldProblemMap* filter,
                               FieldProblemMap* problems,
                               const AddressValidator::Callback& validated)
    : address_(address),
      allow_postal_(allow_postal),
      require_name_(require_name),
      filter_(filter),
      problems_(problems),
      validated_(validated),
      supplied_(BuildCallback(this, &ValidationTask::Validate)),
      lookup_key_(new LookupKey),
      max_depth_(size(LookupKey::kHierarchy)) {
  assert(problems_ != nullptr);
  assert(supplied_ != nullptr);
  assert(lookup_key_ != nullptr);
}

ValidationTask::~ValidationTask() = default;

void ValidationTask::Run(Supplier* supplier) {
  assert(supplier != nullptr);
  problems_->clear();
  lookup_key_->FromAddress(address_);
  max_depth_ = supplier->GetLoadedRuleDepth(lookup_key_->ToKeyString(0));
  supplier->SupplyGlobally(*lookup_key_, *supplied_);
}

void ValidationTask::Validate(bool success,
                              const LookupKey& lookup_key,
                              const Supplier::RuleHierarchy& hierarchy) {
  assert(&lookup_key == lookup_key_.get());  // Sanity check.

  if (success) {
    if (address_.IsFieldEmpty(COUNTRY)) {
      ReportProblemMaybe(COUNTRY, MISSING_REQUIRED_FIELD);
    } else if (hierarchy.rule[0] == nullptr) {
      ReportProblemMaybe(COUNTRY, UNKNOWN_VALUE);
    } else {
      // Checks which use statically linked metadata.
      const std::string& region_code = address_.region_code;
      CheckUnexpectedField(region_code);
      CheckMissingRequiredField(region_code);

      // Checks which use data from the metadata server. Note that
      // CheckPostalCodeFormatAndValue assumes CheckUnexpectedField has already
      // been called.
      CheckUnknownValue(hierarchy);
      CheckPostalCodeFormatAndValue(hierarchy);
      CheckUsesPoBox(hierarchy);
      CheckUnsupportedField();
    }
  }

  validated_(success, address_, *problems_);
  delete this;
}

// A field will return an UNEXPECTED_FIELD problem type if the current value of
// that field is not empty and the field should not be used by that region.
void ValidationTask::CheckUnexpectedField(
    const std::string& region_code) const {
  static const AddressField kFields[] = {
      // COUNTRY is never unexpected.
      ADMIN_AREA,
      LOCALITY,
      DEPENDENT_LOCALITY,
      SORTING_CODE,
      POSTAL_CODE,
      STREET_ADDRESS,
      ORGANIZATION,
      RECIPIENT,
  };

  for (AddressField field : kFields) {
    if (!address_.IsFieldEmpty(field) && !IsFieldUsed(field, region_code)) {
      ReportProblemMaybe(field, UNEXPECTED_FIELD);
    }
  }
}

// A field will return an MISSING_REQUIRED_FIELD problem type if the current
// value of that field is empty and the field is required by that region.
void ValidationTask::CheckMissingRequiredField(
    const std::string& region_code) const {
  static const AddressField kFields[] = {
      // COUNTRY is assumed to have already been checked.
      ADMIN_AREA,
      LOCALITY,
      DEPENDENT_LOCALITY,
      SORTING_CODE,
      POSTAL_CODE,
      STREET_ADDRESS,
      // ORGANIZATION is never required.
      // RECIPIENT is handled separately.
  };

  for (AddressField field : kFields) {
    if (address_.IsFieldEmpty(field) && IsFieldRequired(field, region_code)) {
      ReportProblemMaybe(field, MISSING_REQUIRED_FIELD);
    }
  }

  if (require_name_ && address_.IsFieldEmpty(RECIPIENT)) {
    ReportProblemMaybe(RECIPIENT, MISSING_REQUIRED_FIELD);
  }
}

// A field is UNKNOWN_VALUE if the metadata contains a list of possible values
// for the field and the address data server could not match the current value
// of that field to one of those possible values, therefore returning nullptr.
void ValidationTask::CheckUnknownValue(
    const Supplier::RuleHierarchy& hierarchy) const {
  for (size_t depth = 1; depth < size(LookupKey::kHierarchy); ++depth) {
    AddressField field = LookupKey::kHierarchy[depth];
    if (!(address_.IsFieldEmpty(field) ||
          hierarchy.rule[depth - 1] == nullptr ||
          hierarchy.rule[depth - 1]->GetSubKeys().empty() ||
          hierarchy.rule[depth] != nullptr)) {
      ReportProblemMaybe(field, UNKNOWN_VALUE);
    }
  }
}

void ValidationTask::CheckUnsupportedField() const {
  for (size_t depth = max_depth_; depth < size(LookupKey::kHierarchy);
       ++depth) {
    ReportProblemMaybe(LookupKey::kHierarchy[depth], UNSUPPORTED_FIELD);
  }
}

// Note that it is assumed that CheckUnexpectedField has already been called.
void ValidationTask::CheckPostalCodeFormatAndValue(
    const Supplier::RuleHierarchy& hierarchy) const {
  assert(hierarchy.rule[0] != nullptr);
  const Rule& country_rule = *hierarchy.rule[0];

  if (!(ShouldReport(POSTAL_CODE, INVALID_FORMAT) ||
        ShouldReport(POSTAL_CODE, MISMATCHING_VALUE))) {
    return;
  }

  if (address_.IsFieldEmpty(POSTAL_CODE)) {
    return;
  } else if (std::find(problems_->begin(), problems_->end(),
                       FieldProblemMap::value_type(POSTAL_CODE,
                                                   UNEXPECTED_FIELD))
             != problems_->end()) {
    return;  // Problem already reported.
  }

  // Validate general postal code format. A country-level rule specifies the
  // regular expression for the whole postal code.
  const RE2ptr* format_ptr = country_rule.GetPostalCodeMatcher();
  if (format_ptr != nullptr &&
      !RE2::FullMatch(address_.postal_code, *format_ptr->ptr) &&
      ShouldReport(POSTAL_CODE, INVALID_FORMAT)) {
    ReportProblem(POSTAL_CODE, INVALID_FORMAT);
    return;
  }

  if (!ShouldReport(POSTAL_CODE, MISMATCHING_VALUE)) {
    return;
  }

  for (size_t depth = size(LookupKey::kHierarchy) - 1; depth > 0; --depth) {
    if (hierarchy.rule[depth] != nullptr) {
      // Validate sub-region specific postal code format. A sub-region specifies
      // the regular expression for a prefix of the postal code.
      const RE2ptr* prefix_ptr = hierarchy.rule[depth]->GetPostalCodeMatcher();
      if (prefix_ptr != nullptr) {
        if (!RE2::PartialMatch(address_.postal_code, *prefix_ptr->ptr)) {
          ReportProblem(POSTAL_CODE, MISMATCHING_VALUE);
        }
        return;
      }
    }
  }
}

void ValidationTask::CheckUsesPoBox(
    const Supplier::RuleHierarchy& hierarchy) const {
  assert(hierarchy.rule[0] != nullptr);
  const Rule& country_rule = *hierarchy.rule[0];

  if (allow_postal_ ||
      !ShouldReport(STREET_ADDRESS, USES_P_O_BOX) ||
      address_.IsFieldEmpty(STREET_ADDRESS)) {
    return;
  }

  const auto& matchers = PostBoxMatchers::GetMatchers(country_rule);
  for (const auto& line : address_.address_line) {
    for (auto ptr : matchers) {
      assert(ptr != nullptr);
      if (RE2::PartialMatch(line, *ptr->ptr)) {
        ReportProblem(STREET_ADDRESS, USES_P_O_BOX);
        return;
      }
    }
  }
}

void ValidationTask::ReportProblem(AddressField field,
                                   AddressProblem problem) const {
  problems_->emplace(field, problem);
}

void ValidationTask::ReportProblemMaybe(AddressField field,
                                        AddressProblem problem) const {
  if (ShouldReport(field, problem)) {
    ReportProblem(field, problem);
  }
}

bool ValidationTask::ShouldReport(AddressField field,
                                  AddressProblem problem) const {
  return filter_ == nullptr || filter_->empty() ||
         std::find(filter_->begin(),
                   filter_->end(),
                   FieldProblemMap::value_type(field, problem)) !=
             filter_->end();
}

}  // namespace addressinput
}  // namespace i18n
