chromium/components/autofill/core/browser/form_structure_rationalization_engine.h

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

#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_STRUCTURE_RATIONALIZATION_ENGINE_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_STRUCTURE_RATIONALIZATION_ENGINE_H_

#include <memory>
#include <optional>
#include <string_view>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/country_type.h"
#include "components/autofill/core/browser/field_types.h"

namespace base {
struct Feature;
}

namespace autofill {
class LogManager;
struct ParsingContext;
}  // namespace autofill

namespace autofill::rationalization {

// Container to hold requirements that need to be all fulfilled for a
// rationalization rule to be applied.
struct EnvironmentCondition {};

// Builder class to work around Chromium's "Complex class/struct needs an
// explicit out-of-line constructor." code style requirement which prevents the
// use of designated initializer lists.
class EnvironmentConditionBuilder {};

enum class FieldLocation {};

// Container class for conditions that all need to be true for a field to be
// considered for a rationalization rule.
struct FieldCondition {};

// Container that defines what should happen to fields matched for a
// rationalization rule.
struct SetTypeAction {};

// A declarative rule with conditions and actions. The actions are executed by
// the rationalization engine if all conditions are fulfilled.
struct RationalizationRule {};

// Builder class to work around Chromium's "Complex class/struct needs an
// explicit out-of-line constructor." code style requirement which prevents the
// use of designated initializer lists.
class RationalizationRuleBuilder {};

// This is only exposed for testing purposes.
namespace internal {
bool IsEnvironmentConditionFulfilled(ParsingContext& context,
                                     const EnvironmentCondition& env);

bool IsFieldConditionFulfilledIgnoringLocation(ParsingContext& context,
                                               const FieldCondition& condition,
                                               const AutofillField& field);

// Returns the first index of a field in `fields` that meets the `condition`
// when starting at `start_index` and walking in the direction of
// `condition.location`. Returns std::nullopt if no such field exists.
std::optional<size_t> FindFieldMeetingCondition(
    ParsingContext& context,
    const std::vector<std::unique_ptr<AutofillField>>& fields,
    size_t start_index,
    const FieldCondition& condition);

// Performs rationalization according `rule` if the the conditions of the
// rule are met. The `rule` can be executed multiple times on the `fields`.
// Note that the `fields` vector is const but the fields are mutable. This
// constness is inherited from the calling sites.
void ApplyRuleIfApplicable(
    ParsingContext& context,
    const RationalizationRule& rule,
    const std::vector<std::unique_ptr<AutofillField>>& fields,
    LogManager* log_manager = nullptr);

}  // namespace internal

// Applies a set of `RationalizationRule`s, which are defined in the function
// body.
// Note that the `fields` vector is const but the fields are mutable. This
// constness is inherited from the calling sites.
void ApplyRationalizationEngineRules(
    ParsingContext& context,
    const std::vector<std::unique_ptr<AutofillField>>& fields,
    LogManager* log_manager = nullptr);

}  // namespace autofill::rationalization

#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_STRUCTURE_RATIONALIZATION_ENGINE_H_