/**
 * 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.distributedlog;

import java.io.Serializable;
import java.util.Comparator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LedgerReadPosition {
    static final Logger LOG = LoggerFactory.getLogger(LedgerReadPosition.class);

    private static enum PartialOrderingComparisonResult {
        NotComparable,
        GreaterThan,
        LessThan,
        EqualTo
    }

    long ledgerId = DistributedLogConstants.UNRESOLVED_LEDGER_ID;
    long logSegmentSequenceNo;
    long entryId;

    public LedgerReadPosition(long ledgerId, long logSegmentSequenceNo, long entryId) {
        this.ledgerId = ledgerId;
        this.logSegmentSequenceNo = logSegmentSequenceNo;
        this.entryId = entryId;
    }

    public LedgerReadPosition(LedgerReadPosition that) {
        this.ledgerId = that.ledgerId;
        this.logSegmentSequenceNo = that.logSegmentSequenceNo;
        this.entryId = that.entryId;
    }


    public LedgerReadPosition(final DLSN dlsn) {
        this(dlsn.getLogSegmentSequenceNo(), dlsn.getEntryId());
    }

    public LedgerReadPosition(long logSegmentSequenceNo, long entryId) {
        this.logSegmentSequenceNo = logSegmentSequenceNo;
        this.entryId = entryId;
    }

    public long getLedgerId() {
        if (DistributedLogConstants.UNRESOLVED_LEDGER_ID == ledgerId) {
            LOG.trace("Ledger Id is not initialized");
            throw new IllegalStateException("Ledger Id is not initialized");
        }
        return ledgerId;
    }

    public long getLogSegmentSequenceNumber() {
        return logSegmentSequenceNo;
    }

    public long getEntryId() {
        return entryId;
    }

    public void advance() {
        entryId++;
    }

    public void positionOnNewLogSegment(long ledgerId, long logSegmentSequenceNo) {
        this.ledgerId = ledgerId;
        this.logSegmentSequenceNo = logSegmentSequenceNo;
        this.entryId = 0L;
    }

    @Override
    public String toString() {
        return String.format("(lid=%d, lseqNo=%d, eid=%d)", ledgerId, logSegmentSequenceNo, entryId);
    }

    public boolean definitelyLessThanOrEqualTo(LedgerReadPosition threshold) {
        PartialOrderingComparisonResult result = comparePartiallyOrdered(threshold);
        return ((result == PartialOrderingComparisonResult.LessThan) ||
            (result == PartialOrderingComparisonResult.EqualTo));
    }

    public boolean definitelyLessThan(LedgerReadPosition threshold) {
        PartialOrderingComparisonResult result = comparePartiallyOrdered(threshold);
        return result == PartialOrderingComparisonResult.LessThan;
    }

    private PartialOrderingComparisonResult comparePartiallyOrdered(LedgerReadPosition threshold) {
        // If no threshold is passed we cannot make a definitive comparison
        if (null == threshold) {
            return PartialOrderingComparisonResult.NotComparable;
        }

        if (this.logSegmentSequenceNo != threshold.logSegmentSequenceNo) {
            if (this.logSegmentSequenceNo < threshold.logSegmentSequenceNo) {
                return PartialOrderingComparisonResult.LessThan;
            } else {
                return PartialOrderingComparisonResult.GreaterThan;
            }
        } else if (this.ledgerId != threshold.ledgerId) {
            // When logSegmentSequenceNo is equal we cannot definitely say that this
            // position is less than the threshold unless ledgerIds are equal
            // since LogSegmentSequenceNumber maybe inferred from transactionIds in older
            // versions of the metadata.
            return PartialOrderingComparisonResult.NotComparable;
        } else if (this.getEntryId() < threshold.getEntryId()) {
            return PartialOrderingComparisonResult.LessThan;
        } else if (this.getEntryId() > threshold.getEntryId()) {
            return PartialOrderingComparisonResult.GreaterThan;
        } else {
            return PartialOrderingComparisonResult.EqualTo;
        }
    }

    /**
     * Comparator for the key portion
     */
    public static final ReadAheadCacheKeyComparator COMPARATOR = new ReadAheadCacheKeyComparator();

    // Only compares the key portion
    @Override
    public boolean equals(Object other) {
        if (!(other instanceof LedgerReadPosition)) {
            return false;
        }
        LedgerReadPosition key = (LedgerReadPosition) other;
        return ledgerId == key.ledgerId &&
            entryId == key.entryId;
    }

    @Override
    public int hashCode() {
        return (int) (ledgerId * 13 ^ entryId * 17);
    }

    /**
     * Compare EntryKey.
     */
    protected static class ReadAheadCacheKeyComparator implements Comparator<LedgerReadPosition>, Serializable {

        private static final long serialVersionUID = 0L;

        @Override
        public int compare(LedgerReadPosition left, LedgerReadPosition right) {
            long ret = left.ledgerId - right.ledgerId;
            if (ret == 0) {
                ret = left.entryId - right.entryId;
            }
            return (ret < 0) ? -1 : ((ret > 0) ? 1 : 0);
        }
    }

}


