/*
 * Copyright (c) 2015, Intel Corporation
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of Intel Corporation nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/** \file
 * \brief Bounded repeat compile-time code.
 */

#ifndef REPEATCOMPILE_H
#define REPEATCOMPILE_H

#include "repeat_internal.h"

#include <cstdint>
#include <utility>
#include <vector>

namespace ue2 {

class CharReach;
class depth;

/**
 * \brief Structure representing the various state requirements for a given
 * bounded repeat.
 */
struct RepeatStateInfo {
    RepeatStateInfo(enum RepeatType type, const depth &repeatMin,
                    const depth &repeatMax, u32 minPeriod);

    u32 stateSize;
    u32 packedCtrlSize;
    u32 horizon;
    u32 patchCount;
    u32 patchSize;
    u32 encodingSize;
    u32 patchesOffset;
    std::vector<u32> packedFieldSizes;
    std::vector<uint64_t> table; // not u64a, for boost/gcc-4.9
};

/**
 * \brief Given the parameters of a repeat, choose a repeat implementation
 * type.
 */
enum RepeatType chooseRepeatType(const depth &repeatMin, const depth &repeatMax,
                                 u32 minPeriod, bool is_reset,
                                 bool has_external_guard = false);

u32 calcPackedBytes(u64a val);

bool matches(std::vector<CharReach>::const_iterator a_it,
             std::vector<CharReach>::const_iterator a_ite,
             std::vector<CharReach>::const_iterator b_it,
             std::vector<CharReach>::const_iterator b_ite);

std::vector<size_t>
minResetDistToEnd(const std::vector<std::vector<CharReach>> &triggers,
                  const CharReach &cr);

u32 minPeriod(const std::vector<std::vector<CharReach>> &triggers,
              const CharReach &cr, bool *can_reset);

} // namespace ue2

#endif // REPEATCOMPILE_H
