#!/usr/bin/env perl

use Test::Most;

use autodie;
use feature qw(say);

use List::AllUtils;
use Path::Class qw(dir);

use Bio::MUST::Core;
use Bio::MUST::Core::Utils qw(cmp_store);

my $class = 'Bio::MUST::Core::GeneticCode::Factory';

my @exp_codes = (
    1..6, 9..16, 21..33,
    'Standard',
    'SGC0',
    'Vertebrate Mitochondrial',
    'SGC1',
    'Yeast Mitochondrial',
    'SGC2',
    'Mold Mitochondrial',
    'Protozoan Mitochondrial',
    'Coelenterate Mitochondrial',
    'Mycoplasma',
    'Spiroplasma',
    'SGC3',
    'Invertebrate Mitochondrial',
    'SGC4',
    'Ciliate Nuclear',
    'Dasycladacean Nuclear',
    'Hexamita Nuclear',
    'SGC5',
    'Echinoderm Mitochondrial',
    'Flatworm Mitochondrial',
    'SGC8',
    'Euplotid Nuclear',
    'SGC9',
    'Bacterial, Archaeal and Plant Plastid',
    'Alternative Yeast Nuclear',
    'Ascidian Mitochondrial',
    'Alternative Flatworm Mitochondrial',
    'Blepharisma Macronuclear',
    'Chlorophycean Mitochondrial',
    'Trematode Mitochondrial',
    'Scenedesmus obliquus Mitochondrial',
    'Thraustochytrium Mitochondrial',
    'Rhabdopleuridae Mitochondrial',
    'Candidate Division SR1 and Gracilibacteria',
    'Pachysolen tannophilus Nuclear',
    'Blastocrithidia Nuclear',
    'Condylostoma Nuclear',
    'Karyorelict Nuclear',
    'Mesodinium Nuclear',
    'Peritrich Nuclear',
    'Balanophoraceae Plastid',
    'Cephalodiscidae Mitochondrial',
);

my @translations = (
    [ 'Standard', '1', '+1', <<'CDS',
ATGGGTGATGTTGAGAAGGGCAAGAAGATTTTTGTTCAGAAGTGTGCCCAGTGCCATACCGTGGAAAAGG
GAGGCAAGCACAAGACTGGGCCAAACCTCCATGGTCTATTTGGGCGAAAGACGGGTCAGGCCCCTGGCTT
CTCTTACACAGATGCCAACAAGAACAAAGGCATCACCTGGAAAGAGGAAACACTGATGGAATATTTGGAG
AATCCCAAGAAGTACATCCCTGGAACAAAAATGATCTTTGCTGGCATTAAGAAGAAGACAGAAAGAGAAG
ACTTAATAGCTTATCTCAAAAAAGCTACTAATGAGTAA
CDS
   <<'PEP'
MGDVEKGKKIFVQKCAQCHTVEKGGKHKTGPNLHGLFGRKTGQAPGFSYTDANKNKGITWKEETLMEYLE
NPKKYIPGTKMIFAGIKKKTEREDLIAYLKKATNEx
PEP
    ],
    [ 'Vertebrate Mitochondrial', '2', '+1', <<'CDS',
ATGTTCGCCGACCGTTGACTATTCTCTACAAACCACAAAGACATTGGAACACTATACCTATTATTCGGCG
CATGAGCTGGAGTCCTAGGCACAGCTCTAAGCCTCCTTATTCGAGCCGAGCTGGGCCAGCCAGGCAACCT
TCTAGGTAACGACCACATCTACAACGTTATCGTCACAGCCCATGCATTTGTAATAATCTTCTTCATAGTA
ATACCCATCATAATCGGAGGCTTTGGCAACTGACTAGTTCCCCTAATAATCGGTGCCCCCGATATGGCGT
TCCCCCGCATAAACAACATAAGCTTCTGACTCTTACCCCCCTCTCTCCTACTCCTGCTCGCATCTGCTAT
AGTGGAGGCCGGAGCAGGAACAGGTTGAACAGTCTACCCTCCCTTAGCAGGGAACTACTCCCACCCTGGA
GCCTCCGTAGACCTAACCATCTTCTCCTTACACCTAGCAGGTGTCTCCTCTATCTTAGGGGCCATCAATT
TCATCACAACAATTATCAATATAAAACCCCCTGCCATAACCCAATACCAAACGCCCCTCTTCGTCTGATC
CGTCCTAATCACAGCAGTCCTACTTCTCCTATCTCTCCCAGTCCTAGCTGCTGGCATCACTATACTACTA
ACAGACCGCAACCTCAACACCACCTTCTTCGACCCCGCCGGAGGAGGAGACCCCATTCTATACCAACACC
TATTCTGATTTTTCGGTCACCCTGAAGTTTATATTCTTATCCTACCAGGCTTCGGAATAATCTCCCATAT
TGTAACTTACTACTCCGGAAAAAAAGAACCATTTGGATACATAGGTATGGTCTGAGCTATGATATCAATT
GGCTTCCTAGGGTTTATCGTGTGAGCACACCATATATTTACAGTAGGAATAGACGTAGACACACGAGCAT
ATTTCACCTCCGCTACCATAATCATCGCTATCCCCACCGGCGTCAAAGTATTTAGCTGACTCGCCACACT
CCACGGAAGCAATATGAAATGATCTGCTGCAGTGCTCTGAGCCCTAGGATTCATCTTTCTTTTCACCGTA
GGTGGCCTGACTGGCATTGTATTAGCAAACTCATCACTAGACATCGTACTACACGACACGTACTACGTTG
TAGCTCACTTCCACTATGTCCTATCAATAGGAGCTGTATTTGCCATCATAGGAGGCTTCATTCACTGATT
TCCCCTATTCTCAGGCTACACCCTAAACCAAACCTACGCCAAAATCCATTTCGCTATCATATTCATCGGC
GTAAATCTAACTTTCTTCCCACAACACTTTCTCGGCCTATCCGGAATGCCCCGACGTTACTCGGACTACC
CCGATGCATACACCACATGAAATGTCCTATCATCTGTAGGCTCATTCATTTCTCTAACAGCAGTAATATT
AATAATTTTCATGATTTGAGAAGCCTTCGCTTCGAAGCGAAAAGTCCTAATAGTAGAAGAACCCTCCATA
AACCTGGAGTGACTATATGGATGCCCCCCACCCTACCACACATTCGAAGAACCCGTATACATAAAATCTA
GA
CDS
    <<'PEP'
MFADRWLFSTNHKDIGTLYLLFGAWAGVLGTALSLLIRAELGQPGNLLGNDHIYNVIVTAHAFVMIFFMV
MPIMIGGFGNWLVPLMIGAPDMAFPRMNNMSFWLLPPSLLLLLASAMVEAGAGTGWTVYPPLAGNYSHPG
ASVDLTIFSLHLAGVSSILGAINFITTIINMKPPAMTQYQTPLFVWSVLITAVLLLLSLPVLAAGITMLL
TDRNLNTTFFDPAGGGDPILYQHLFWFFGHPEVYILILPGFGMISHIVTYYSGKKEPFGYMGMVWAMMSI
GFLGFIVWAHHMFTVGMDVDTRAYFTSATMIIAIPTGVKVFSWLATLHGSNMKWSAAVLWALGFIFLFTV
GGLTGIVLANSSLDIVLHDTYYVVAHFHYVLSMGAVFAIMGGFIHWFPLFSGYTLNQTYAKIHFAIMFIG
VNLTFFPQHFLGLSGMPRRYSDYPDAYTTWNVLSSVGSFISLTAVMLMIFMIWEAFASKRKVLMVEEPSM
NLEWLYGCPPPYHTFEEPVYMKSx
PEP
    ],
    [ 'Chlorophycean Mitochondrial', '16', '+2', <<'CDS',
TATGCGTTGGTTGTATTCTACTTCTCATAAAGATATTGGTTTGTTGTACTTGGTATTCGCCTTCTTTGGC
GGTTTGCTAGGTACTTCTCTAAGTATGTTGATTCGTTACGAGTTGGCTTTGCCAGGTCGTGGCTTGTTGG
ACGGTAACGGTCAACTATATAACGTCATTATTACCGGTCACGGTATTATCATGCTATTGTTCATGGTAAT
GCCAGCCCTATTCGGTGGTTTTGGTAACTGGTTGCTACCAATCATGATCGGTGCCCCAGACATGGCTTTC
CCTCGTCTAAACAACATTAGTTTCTGGCTGAACCCACCAGCCCTGGCTTTGTTGCTATTGTCTACTTTGG
TAGAGCAAGGCCCCGGTACTGGTTGGACCGCTTATCCACCACTAAGCGTACAACACAGCGGTACTAGCGT
AGATTTGGCTATTTTGAGCTTGCACTTGAACGGTTTGAGCTCTATTTTGGGTGCTGTCAACATGTTGGTC
ACTGTAGCTGGTTTGCGTGCCCCAGGTATGAAACTGTTGCACATGCCATTGTTCGTATGGGCCATTGCTT
TGACTGCTGTATTGGTCATTTTGGCCGTACCAGTATTGGCTGCCGCTTTGGTTATGTTGCTGACTGACCG
TAACATCAACACTGCTTACTTCTGTGAGTCTGGTGATTTGATTTTGTATCAGCACTTGTTCTGGTTCTTT
GGTCACCCTGAGGTCTACATTTTGATCTTGCCAGCTTTCGGTATTGTTAGCCAAGTTGTAAGTTTCTTCA
GTCAAAAACCAGTATTTGGTTTGACTGGTATGATTTGCGCTATGGGTGCCATTAGTTTGCTAGGTTTCAT
TGTATGGGCTCATCACATGTTTACCGTCGGCCTAGATTTGGACACCGTCGCTTACTTTACTAGCGCTACC
ATGATTATTGCCGTACCAACTGGTATGAAAATTTTCAGCTGGATGGCTACCATCTACTCTGGTCGCGTAT
GGTTCACCACTCCAATGTGGTTTGCTGTCGGTTTTATTTGCCTGTTTACTCTAGGTGGTGTAACTGGTGT
CGTACTAGCTAACGCTGGTGTTGACATGCTTGTACACGATACCTACTACGTAGTAGCTCACTTCCACTAC
GTCTTGAGTATGGGTGCCGTTTTCGGTATTTTCGCTGGTGTCTACTTCTGGGGTAACCTAATTACTGGTT
TGGGCTACCACGAGGGTCGTGCTATGGTACACTTCTGGTTGCTATTCATTGGTGTCAACTTGACCTTCTT
CCCACAACACTTCTTGGGTTTGGCTGGTATGCCACGCCGTATGTTCGATTATGCTGACTGCTTTGCCGGT
TGGAACGCTGTTAGTAGCTTCGGTGCTAGCATTAGCTTCATCAGTGTAATCGTATTTGCCACTACTTTCC
AAGAGGCTGTTCGCACCGTACCTCGTACTGCTACTACTCTAGAGTGGGTTTTGCTAGCTACTCCAGCTCA
CCACGCCTTGAGTCAAGTACCAGTCTTGCGTACTGCCAGCTCTCACTAA
CDS
    <<'PEP'
MRWLYSTSHKDIGLLYLVFAFFGGLLGTSLSMLIRYELALPGRGLLDGNGQLYNVIITGHGIIMLLFMVM
PALFGGFGNWLLPIMIGAPDMAFPRLNNISFWLNPPALALLLLSTLVEQGPGTGWTAYPPLSVQHSGTSV
DLAILSLHLNGLSSILGAVNMLVTVAGLRAPGMKLLHMPLFVWAIALTAVLVILAVPVLAAALVMLLTDR
NINTAYFCESGDLILYQHLFWFFGHPEVYILILPAFGIVSQVVSFFSQKPVFGLTGMICAMGAISLLGFI
VWAHHMFTVGLDLDTVAYFTSATMIIAVPTGMKIFSWMATIYSGRVWFTTPMWFAVGFICLFTLGGVTGV
VLANAGVDMLVHDTYYVVAHFHYVLSMGAVFGIFAGVYFWGNLITGLGYHEGRAMVHFWLLFIGVNLTFF
PQHFLGLAGMPRRMFDYADCFAGWNAVSSFGASISFISVIVFATTFQEAVRTVPRTATTLEWVLLATPAH
HALSQVPVLRTASSHx
PEP
    ],
    [ 'Blepharisma Macronuclear', '15', '-3', <<'CDS',
ttaaccaccgaatccatagagggtctttccttgtctcttgagagcgtagactacatcaagagcggtgaca
gtctttctcttggcgtgctcggtgtaggtgactgagtctctgatgactgactcaaggaatcccttgagga
cagctctggtctcttcatagacgagggatgaaattctcttgacaccacctcttctagctaatcttctgat
agctggcttggtgactcccaagatagtctctctgagggccttcttggcgtgtctcttggctccgaccttt
ccgtaaccttttcctccttttcctccttttcctcttcctggcatat
CDS
    <<'PEP'
MPGRGKGGKGGKGYGKVGAKRHAKKALRETILGVTKPAIRRLARRGGVKRISSLVYEETRAVLKGFLESV
IRDSVTYTEHAKRKTVTALDVVYALKRQGKTLYGFGGx
PEP
    ],
    [ 'Standard', '1', '+1', <<'CDS',
ATGCAGGTCATCGTCGCCTCTCCTCCGCTCATCTCCGCCGCTTSTCTCTCTAAACCTTTSCATTCTCTCT
CTAAGGCCGCACTCTCTTTCTCTAGAGYCAAACCCATTTKCCCTTTCCCCCAAACCTCACGACCCATCTC
CGTCTACAAATCCCCRATGAACAACCTCTTCAACAGGCTCGGTTTCGGGTCTCGTCCCCAAGCTCAAGTC
GMCCCAWCTTCCGCCGCAATCGCCCAAGGACCCGACGACGATGTTCCGKCRCCAGGTCAGCAATTCRCGC
AATTCGGCGCCGGTTGCTTCTGGGGAGTGGAGCTAGCTTACCAGAGAGTTCCTGGTGTGACCAAGACCGA
GGTTGGGTATAGCCATGGCCTCATGCACAATCCGAGTTACGAAGATGTCTGTACTGGCACGACGGGACAC
AACGAGGTTGTTAGAGTTCAGTACGATCCGAAAGAGTGTAGCTTTGAGACCTTGCTCGATGTTTTCTGGA
ATCGCCATGATCCAACCACCTTGAATCGTCAGGGGGGCGATGTGGGAACTCAGTATCGATCAGGCATATA
CTACTACACAGACGAGCAAGAGCGCATAGCTCGTGAAGCCGTTGAGAAACAGCAGAAGATATTGAACAAG
AAGATTGTGACAGAGATACTTCCCGCSACAAAATTCTACAGAGCAGAAAATTACCATCAGCAATACCTGG
CAAAAGGCGGTCGCATGGGTTTAAGACAATCAGCTGNGAAAGGTTGCAAGGATCCAATCCGATGTTACGG
C
CDS
    <<'PEP'
MQVIVASPPLISAAxLSKPxHSLSKAALSFSRxKPIxPFPQTSRPISVYKSPMNNLFNRLGFGSRPQAQV
xPxSAAIAQGPDDDVPxPGQQFxQFGAGCFWGVELAYQRVPGVTKTEVGYSHGLMHNPSYEDVCTGTTGH
NEVVRVQYDPKECSFETLLDVFWNRHDPTTLNRQGGDVGTQYRSGIYYYTDEQERIAREAVEKQQKILNK
KIVTEILPATKFYRAENYHQQYLAKGGRMGLRQSAxKGCKDPIRCYG
PEP
    ],
);

{
    # create factory from the web
    my $gc_fac = $class->new;
    isa_ok $gc_fac, $class;
    my @codes = $gc_fac->list_codes;
    ok @codes, 'successfully created factory from the web';
}

{
    # create factory from local database
    my $tax_dir = dir('test', 'taxdump')->stringify;
    my $gc_fac = $class->new( tax_dir => $tax_dir );
    isa_ok $gc_fac, $class;
    my @codes = $gc_fac->list_codes;
    ok @codes, 'successfully created factory from local database';

    cmp_bag \@codes, \@exp_codes, 'got expected code list';

    for my $exp_row (@translations) {

        my ($name, $id, $frame, $nt, $aa) = @{$exp_row};
        my $code = $gc_fac->code_for($name);
        isa_ok $code, 'Bio::MUST::Core::GeneticCode';
        cmp_ok $code->ncbi_id, 'eq', $id,
            "got expected NCBI id $id for code $name";

        my $nt_seq = Bio::MUST::Core::Seq->new(seq_id => 'seq', seq => $nt);
        my $aa_seq = Bio::MUST::Core::Seq->new(seq_id => 'seq', seq => $aa);
        cmp_ok $code->translate($nt_seq, $frame)->seq, 'eq', $aa_seq->seq,
            "got expected translation for code $id and frame $frame";
    }
}


done_testing;
