/*
     Description: 单个sam记录需要保存的数据

     Copyright : All right reserved by ICT

     Author : Zhang Zhonghai
     Date : 2025/12/24
*/

#pragma once

#include <vector>

#include "covariate.h"
#include "util/bam_wrap.h"
#include "util/stable_array.h"
using std::vector;

struct ReadRecalInfo {
    SamData& read;
    int length;
    PerReadCovariateMatrix& covariates;
    StableArray<uint8_t>& skips;
    StableArray<uint8_t>&base_quals, &ins_quals, &del_quals;
    StableArray<double>&snp_errs, &ins_errs, &del_errs;

    ReadRecalInfo(SamData& _read, PerReadCovariateMatrix& _covariates, StableArray<uint8_t>& _skips, StableArray<double>& _snp_errs,
                  StableArray<double>& _ins_errs, StableArray<double>& _del_errs)
        : read(_read),
          covariates(_covariates),
          skips(_skips),
          base_quals(_read.base_quals),
          ins_quals(_read.ins_quals),
          del_quals(_read.del_quals),
          snp_errs(_snp_errs),
          ins_errs(_ins_errs),
          del_errs(_del_errs) {
        length = _read.read_len;
    }

    /**
     * Get the qual score for event type at offset
     *
     * @param eventType the type of event we want the qual for
     * @param offset the offset into this read for the qual
     * @return a valid quality score for event at offset
     */
    // 获取跟eventType对应的quality
    uint8_t getQual(const EventTypeValue &event, const int offset) {
        if (event == EventType::BASE_SUBSTITUTION) {
            return base_quals[offset];
        } else if (event == EventType::BASE_INSERTION) {
            return ins_quals[offset];
        } else {
            return del_quals[offset];
        }
    }

    /**
     * Get the error fraction for event type at offset
     *
     * The error fraction is a value between 0 and 1 that indicates how much certainty we have
     * in the error occurring at offset.  A value of 1 means that the error definitely occurs at this
     * site, a value of 0.0 means it definitely doesn't happen here.  0.5 means that half the weight
     * of the error belongs here
     *
     * @param eventType the type of event we want the qual for
     * @param offset the offset into this read for the qual
     * @return a fractional weight for an error at this offset
     */
    double getErrorFraction(const EventTypeValue& event, const int offset) {
        if (event == EventType::BASE_SUBSTITUTION) {
            return snp_errs[offset];
        } else if (event == EventType::BASE_INSERTION) {
            return ins_errs[offset];
        } else {
            return del_errs[offset];
        }
    }
};