// pcr.sy -- Polymerase Chain Reaction and diagnostic molecular biology.
//
// PCR, RT-PCR, qPCR/RT-qPCR, and primer design rules as native Scyla.
// The molecular diagnostic workhorse — from COVID testing to forensics
// to paternity to cancer mutation detection.
//
// Sources:
//   Mullis K et al. Methods Enzymol 155:335-350, 1987 (PCR invention, Nobel 1993)
//   Higuchi R et al. Biotechnology 10:413-417, 1992 (real-time PCR)
//   Corman VM et al. Euro Surveill 25:2000045, 2020 (SARS-CoV-2 RT-qPCR protocol)
//
// Marjorie McCubbins + Aether, April 2026
// Patent pending: 64/034,536

struct PCRStep {
    step_number: Int,
    name: String,
    temperature: Float,
    duration: String,
    mechanism: String,
    key_enzyme: String,
    enzyme_accession: String,
    citation: String,
}

struct PCRVariant {
    name: String,
    abbreviation: String,
    input_template: String,
    key_difference: String,
    clinical_use: String,
    detection_method: String,
    citation: String,
}

struct PrimerRule {
    rule_name: String,
    description: String,
    optimal_value: String,
    citation: String,
}

fn pcrstep(sn: Int, n: String, t: Float, d: String, m: String, ke: String, ea: String, ci: String) -> PCRStep {
    return PCRStep { step_number: sn, name: n, temperature: t, duration: d, mechanism: m, key_enzyme: ke, enzyme_accession: ea, citation: ci }
}

fn pcrvar(n: String, ab: String, it: String, kd: String, cu: String, dm: String, ci: String) -> PCRVariant {
    return PCRVariant { name: n, abbreviation: ab, input_template: it, key_difference: kd, clinical_use: cu, detection_method: dm, citation: ci }
}

fn prule(rn: String, d: String, ov: String, ci: String) -> PrimerRule {
    return PrimerRule { rule_name: rn, description: d, optimal_value: ov, citation: ci }
}

// ═══════════════════════════════════════════════════════
// THE THREE STEPS OF PCR (one cycle)
// ═══════════════════════════════════════════════════════

fn pcr_step(step: Int) -> PCRStep {
    if step == 1 { return pcrstep(1, "Denaturation", 94.0, "15-30 seconds", "Heat separates dsDNA into two ssDNA strands by breaking hydrogen bonds between base pairs. All secondary structure melted.", "None (thermal)", "", "Mullis K et al. Methods Enzymol 155:335-350, 1987") }
    if step == 2 { return pcrstep(2, "Annealing", 55.0, "15-60 seconds", "Temperature lowered to allow primers to bind (anneal) to complementary sequences on each ssDNA template. Primer Tm determines optimal annealing temperature (~5C below Tm).", "None (primers bind by complementarity)", "", "Mullis 1987") }
    if step == 3 { return pcrstep(3, "Extension", 72.0, "30-90 seconds (1 min/kb)", "Taq polymerase extends primers 5' to 3', synthesizing new complementary strand using dNTPs. Optimal temperature for Taq is 72C. Each cycle doubles the target.", "Taq DNA polymerase", "P19821", "Mullis 1987. Taq from Thermus aquaticus: Chien A et al. J Bacteriol 127:1550-1557, 1976.") }
    return pcrstep(0, "", 0.0, "", "", "", "", "")
}

fn pcr_amplification(cycles: Int) -> String {
    // 2^n amplification: 30 cycles = ~1 billion copies
    if cycles == 20 { return "~1 million copies (2^20 = 1,048,576)" }
    if cycles == 25 { return "~33 million copies (2^25 = 33,554,432)" }
    if cycles == 30 { return "~1 billion copies (2^30 = 1,073,741,824)" }
    if cycles == 35 { return "~34 billion copies (2^35 = 34,359,738,368)" }
    if cycles == 40 { return "~1 trillion copies (2^40 = 1,099,511,627,776). WARNING: >35 cycles increases false positive risk from trace contamination." }
    return "2^n copies where n = cycle count"
}

// ═══════════════════════════════════════════════════════
// PCR VARIANTS
// ═══════════════════════════════════════════════════════

fn pcr_variant(name: String) -> PCRVariant {
    if name == "standard" { return pcrvar("Standard PCR", "PCR", "dsDNA", "Basic thermal cycling with Taq. Endpoint detection (gel electrophoresis).", "Genotyping, cloning, forensics, paternity testing.", "Agarose gel electrophoresis + ethidium bromide/SYBR Safe staining.", "Mullis 1987") }
    if name == "rt_pcr" { return pcrvar("Reverse Transcription PCR", "RT-PCR", "RNA (mRNA or viral RNA)", "Step 0: reverse transcriptase converts RNA to cDNA. Then standard PCR on cDNA. Detects RNA viruses and gene expression.", "COVID-19 diagnosis (SARS-CoV-2 RNA detection). HIV viral load. Gene expression analysis.", "Gel or real-time fluorescence.", "Corman VM et al. Euro Surveill 25:2000045, 2020") }
    if name == "qpcr" { return pcrvar("Quantitative real-time PCR", "qPCR / RT-qPCR", "DNA or cDNA (from RNA)", "Fluorescent reporter measured each cycle in real-time. Ct (cycle threshold) value = cycle where fluorescence crosses threshold. Lower Ct = more starting template.", "COVID-19 diagnostic standard (Ct < 40 = positive). Viral load quantification. Gene expression (relative or absolute). Cancer mutation detection.", "TaqMan probes (sequence-specific) or SYBR Green (intercalating dye, non-specific).", "Higuchi R et al. Biotechnology 10:413-417, 1992") }
    if name == "ddpcr" { return pcrvar("Digital Droplet PCR", "ddPCR", "DNA or cDNA", "Sample partitioned into ~20,000 droplets. Each droplet = independent PCR reaction. Count positive vs negative droplets. Absolute quantification without standard curve.", "Liquid biopsy (circulating tumor DNA). Rare mutation detection. Copy number variation. Minimal residual disease.", "Fluorescence per droplet, Poisson statistics for absolute count.", "Hindson BJ et al. Anal Chem 83:8604-8610, 2011") }
    if name == "multiplex" { return pcrvar("Multiplex PCR", "mPCR", "DNA", "Multiple primer pairs in one reaction. Amplifies several targets simultaneously. Requires careful primer design (no cross-reactivity).", "Respiratory pathogen panels (flu A/B + RSV + COVID simultaneously). STR analysis (forensics). Newborn screening.", "Gel, capillary electrophoresis, or real-time with multiple fluorophores.", "Chamberlain JS et al. Nucleic Acids Res 16:11141-11156, 1988") }
    if name == "lamp" { return pcrvar("Loop-mediated Isothermal Amplification", "LAMP", "DNA or RNA (with RT)", "Isothermal (65C constant, no thermocycler needed). Uses 4-6 primers and Bst polymerase with strand displacement activity. Results in 15-60 minutes. Turbidity or color change readout.", "Point-of-care COVID testing. Resource-limited settings. Field diagnostics (agriculture, veterinary).", "Visual turbidity (magnesium pyrophosphate precipitate), pH indicator color change, or fluorescence.", "Notomi T et al. Nucleic Acids Res 28:e63, 2000") }
    return pcrvar("", "", "", "", "", "", "")
}

// ═══════════════════════════════════════════════════════
// COVID-19 RT-qPCR SPECIFICS
// ═══════════════════════════════════════════════════════

fn covid_pcr_target(target: String) -> String {
    if target == "E_gene" { return "E gene (envelope). Pan-sarbecovirus screening target. First-line in WHO/Charite protocol. High sensitivity. Cited: Corman VM et al. Euro Surveill 25:2000045, 2020." }
    if target == "RdRp" { return "RdRp gene (nsp12). Confirmatory target. SARS-CoV-2 specific. Two probes: P1 (both SARS-CoV) and P2 (SARS-CoV-2 only). Cited: Corman 2020." }
    if target == "N_gene" { return "N gene (nucleocapsid). CDC protocol primary targets: N1 and N2 regions. High copy number in infected cells. Used in most commercial assays. Cited: CDC 2019-nCoV RT-qPCR Diagnostic Panel." }
    if target == "S_gene" { return "S gene (spike). Target gene dropout (SGTF) used as proxy for certain variants (Alpha had del69-70 causing S-gene target failure in ThermoFisher TaqPath assay). Cited: Volz E et al. Cell 184:64-75, 2021." }
    if target == "ORF1ab" { return "ORF1ab (nonstructural polyprotein region). Large gene, multiple probe designs possible. Used in some Chinese CDC and commercial protocols." }
    return ""
}

fn covid_ct_interpretation(ct: Float) -> String {
    if ct < 15.0 { return "Very high viral load. Strongly positive. Highly infectious. Early acute infection or high-shedding phase." }
    if ct < 25.0 { return "High viral load. Positive. Likely infectious. Active infection." }
    if ct < 30.0 { return "Moderate viral load. Positive. May be infectious. Could be early or resolving infection." }
    if ct < 35.0 { return "Low viral load. Positive. Unlikely to be infectious. Late infection or recovering." }
    if ct < 40.0 { return "Very low viral load. Weak positive. May represent residual RNA, not active virus. Repeat testing recommended." }
    return "Negative (Ct >= 40 or undetermined). No viral RNA detected above threshold."
}

// ═══════════════════════════════════════════════════════
// PRIMER DESIGN RULES
// ═══════════════════════════════════════════════════════

fn primer_rule(rule: String) -> PrimerRule {
    if rule == "length" { return prule("Primer length", "Primers should be 18-25 nucleotides long. Shorter = less specific. Longer = slower annealing.", "18-25 nt", "Dieffenbach CW et al. PCR Methods Appl 3:S30-37, 1993") }
    if rule == "tm" { return prule("Melting temperature (Tm)", "Both primers should have similar Tm. Tm determines annealing temperature (Ta = Tm - 5C).", "55-65 C, within 2C of each other", "Dieffenbach 1993") }
    if rule == "gc_content" { return prule("GC content", "GC pairs have 3 hydrogen bonds (vs 2 for AT). Higher GC = higher Tm. 40-60% GC is optimal.", "40-60%", "Dieffenbach 1993") }
    if rule == "gc_clamp" { return prule("GC clamp", "End primers with 1-2 G or C bases at 3' end for strong binding. But avoid >3 consecutive G/C (non-specific binding).", "1-2 G/C at 3' end", "Dieffenbach 1993") }
    if rule == "no_dimers" { return prule("No primer dimers", "Avoid complementarity between forward and reverse primers, especially at 3' ends. Dimers waste reagents and reduce yield.", "No 3' complementarity > 3 bp", "Dieffenbach 1993") }
    if rule == "no_hairpin" { return prule("No hairpins", "Avoid internal complementarity that forms stem-loop structures. Hairpins prevent primer from binding template.", "No internal palindromes > 4 bp", "Dieffenbach 1993") }
    if rule == "product_size" { return prule("Amplicon size", "Standard PCR: 100-1000 bp. qPCR: 70-200 bp (shorter = more efficient). Long-range PCR: up to 40 kb.", "qPCR: 70-200 bp", "Dieffenbach 1993") }
    return prule("", "", "", "")
}

// ═══════════════════════════════════════════════════════
// QUICK ACCESS
// ═══════════════════════════════════════════════════════

fn pcr_step_count() -> Int {
    return 3
}

fn pcr_variant_count() -> Int {
    return 6
}

fn primer_rule_count() -> Int {
    return 7
}

fn taq_optimal_temp() -> Float {
    return 72.0
}

fn typical_pcr_cycles() -> Int {
    return 30
}
