/*
 * Copyright (c) 2022, Technische Universität Kaiserslautern
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder 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 HOLDER
 * 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.
 *
 * Authors:
 *    Iron Prando da Silva
 */

#include "DDR5dbphaseentry.h"

DDR5DBPhaseEntry::DDR5DBPhaseEntry(const QSqlQuery& query) {
    id = query.value(0).toLongLong();
    phaseName = StringMapper(query.value(1).toString());
    phaseBegin = query.value(2).toLongLong();
    phaseEnd = query.value(3).toLongLong();
    transact = query.value(4).toLongLong();
    tBank = query.value(5).toLongLong();
    tBankgroup = query.value(6).toLongLong();
    tRank = query.value(7).toLongLong();
    tBurstLength = query.value(8).toLongLong();

}

bool DDR5DBPhaseEntry::potentialDependency(const TimeDependency& dep, const std::shared_ptr<DBPhaseEntryBase> otherPhase) {
    auto other = std::dynamic_pointer_cast<DDR5DBPhaseEntry>(otherPhase);
    if (!other) return false;

    if (dep.passFunction && !dep.passFunction->execute(shared_from_this(), other)) return false;

    bool isCmdPool = dep.phaseDep == StringMapper::Identifier::CMD_BUS;

    bool const skipOnIntraBankAndDifferentBanks = {
        dep.depType == DependencyType::IntraBank 
        && tBank != other->tBank
    };
    bool const skipOnIntraBankgroupAndDifferentBankgroup = {
        dep.depType == DependencyType::IntraBankGroup
        && tBankgroup != other->tBankgroup
    };
    bool const skipOnIntraBankInGroupAndDifferentBankInGroup = {
        dep.depType == DependencyType::IntraBankInGroup
        && tBankInGroup != other->tBankInGroup
    };
    bool const skipOnIntraLogRankAndDifferentRanks = {
        dep.depType == DependencyType::IntraLogicalRank 
        && tLogicalRank != other->tLogicalRank
    };
    bool const skipOnIntraPhysRankAndDifferentRanks = {
        dep.depType == DependencyType::IntraPhysicalRank 
        && tPhysicalRank != other->tPhysicalRank
    };
    bool const skipOnIntraDIMMRankAndDifferentRanks = {
        dep.depType == DependencyType::IntraDIMMRank 
        && tDIMMRank != other->tDIMMRank
    };
    bool const skipOnInterDIMMRankAndSameRank = {
        dep.depType == DependencyType::InterDIMMRank
        && tDIMMRank == other->tDIMMRank
        && !isCmdPool
    };
    
    return !(
        skipOnIntraBankAndDifferentBanks
        || skipOnIntraBankgroupAndDifferentBankgroup
        || skipOnIntraBankInGroupAndDifferentBankInGroup
        || skipOnIntraLogRankAndDifferentRanks
        || skipOnIntraPhysRankAndDifferentRanks
        || skipOnIntraDIMMRankAndDifferentRanks
        || skipOnInterDIMMRankAndSameRank
    );
}
