/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 *
 */

package org.apache.jackrabbit.oak.segment.file.tar;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.Objects;
import org.apache.jackrabbit.oak.segment.file.tar.index.IndexEntry;
import org.apache.jackrabbit.oak.segment.spi.persistence.SegmentArchiveEntry;
import org.jetbrains.annotations.NotNull;

/**
 * Instances of this class represent the garbage collection generation related
 * information of a segment. It consists of the segment's generation, its full
 * generation and its compaction flag. The segment's generation records the number
 * of garbage collection cycles a segment went through and is incremented with
 * every garbage collection regardless its type. The segment's full generation
 * records the number of full garbage collection cycles a segment went through.
 * It is only incremented on full garbage collection cycles. The segment's compaction
 * flag is set for those segments that have been created by a compaction operation.
 * It is never set for segments created by normal write operations or defer
 * compactions triggered by such. Segments written by normal repository writes will
 * inherit the generation and full generation of the segment written by the previous
 * compaction process with the compacted flag cleared.
 * <p>
 * The information recorded in this way allows to determine the reclamation status
 * of a segment by just looking at the {@code GCGeneration} instances of that segment
 * and of the segment containing the repository head: Let {@code s} be a segment,
 * {@code h} be the segment containing the current repository head and {@code n} be
 * the number of retained generations.
 * <ul>
 *     <li>{@code s} is old iff {@code h.generation - s.generation >= n}</li>
 *     <li>{@code s} is in the same compaction tail than h iff
 *         {@code s.isCompacted && s.fullGeneration == h.fullGeneration}</li>
 *     <li>{@code s} is reclaimable iff {@code s} is old and {@code s} is not in the same compaction tail than {@code h}</li>
 * </ul>
 */
public final class GCGeneration {

    public static final GCGeneration NULL = new GCGeneration(0, 0, false);

    public static GCGeneration newGCGeneration(int generation, int fullGeneration, boolean isCompacted) {
        return new GCGeneration(generation, fullGeneration, isCompacted);
    }

    public static GCGeneration newGCGeneration(SegmentArchiveEntry indexEntry) {
        return new GCGeneration(indexEntry.getGeneration(), indexEntry.getFullGeneration(), indexEntry.isCompacted());
    }

    private final int generation;

    private final int fullGeneration;

    private final boolean isCompacted;

    private GCGeneration(int generation, int fullGeneration, boolean isCompacted) {
        this.generation = generation;
        this.fullGeneration = fullGeneration;
        this.isCompacted = isCompacted;
    }

    public int getGeneration() {
        return generation;
    }

    public int getFullGeneration() {
        return fullGeneration;
    }

    public boolean isCompacted() {
        return isCompacted;
    }

    /**
     * Create a new instance with the generation and the full generation incremented by one
     * and the compaction flag left unchanged.
     */
    @NotNull
    public GCGeneration nextFull() {
        return new GCGeneration(generation + 1, fullGeneration + 1, true);
    }

    /**
     * Create a new instance with the generation incremented by one and the full
     * generation and the compaction flag left unchanged.
     */
    @NotNull
    public GCGeneration nextTail() {
        return new GCGeneration(generation + 1, fullGeneration, true);
    }

    /**
     * Create a new instance with the compaction flag unset and the generation and the
     * full generation left unchanged.
     */
    @NotNull
    public GCGeneration nonGC() {
        return new GCGeneration(generation, fullGeneration, false);
    }

    /**
     * Compare this generation with {@code gcGeneration}
     * @param gcGeneration  the generation this generation is compared against.
     * @return  Number of generations between this generation and {@code gcGeneration}
     */
    public int compareWith(@NotNull GCGeneration gcGeneration) {
        return generation - checkNotNull(gcGeneration).generation;
    }

    /**
     * Compare this full generation the full generation of {@code gcGeneration}
     * @param gcGeneration  the generation this generation is compared against.
     * @return  Number of generations between the full generations of this generation
     *          and {@code gcGeneration}
     */
    public int compareFullGenerationWith(@NotNull GCGeneration gcGeneration) {
        return fullGeneration - checkNotNull(gcGeneration).fullGeneration;
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if (other == null || getClass() != other.getClass()) {
            return false;
        }
        GCGeneration that = (GCGeneration) other;
        return generation == that.generation
                && fullGeneration == that.fullGeneration
                && isCompacted == that.isCompacted;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(generation, fullGeneration, isCompacted);
    }

    @Override
    public String toString() {
        return "GCGeneration{" +
                "generation=" + generation + ',' +
                "fullGeneration=" + fullGeneration +  ',' +
                "isCompacted=" + isCompacted + '}';
    }

}
