1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16export class StringFasta  {
17    static readonly ALU : String = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" + "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" + "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" + "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" + "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" + "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" + "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
18    static IUB : HashMap<Char, Double> = new HashMap();
19    static HomoSap : HashMap<Char, Double> = new HashMap();
20    static {
21        IUB.put(c'a', 0.2);
22        IUB.put(c'c', 0.2);
23        IUB.put(c'g', 0.2);
24        IUB.put(c't', 0.2);
25        IUB.put(c'B', 0.2);
26        IUB.put(c'D', 0.2);
27        IUB.put(c'H', 0.2);
28        IUB.put(c'K', 0.2);
29        IUB.put(c'M', 0.2);
30        IUB.put(c'N', 0.2);
31        IUB.put(c'R', 0.2);
32        IUB.put(c'S', 0.2);
33        IUB.put(c'V', 0.2);
34        IUB.put(c'W', 0.2);
35        IUB.put(c'Y', 0.2);
36        HomoSap.put(c'a', 0.3029549426680);
37        HomoSap.put(c'c', 0.1979883004921);
38        HomoSap.put(c'g', 0.1975473066391);
39        HomoSap.put(c't', 0.3015094502008);
40    }
41    static class Random  {
42        static last : int = 42;
43        static A : int = 3877;
44        static C : int = 29573;
45        static M : int = 139968;
46        public static rand(max : double): double {
47            last = (last * A + C) % M;
48            return max * last / M;
49        }
50    }
51
52    static makeCumulative(table : HashMap<Char, Double>): void {
53        let last : Char = null;
54        for (let entry : HashMap.Entry<Char, Double> of table.entrySet()){
55            let c : Char = entry.getKey();
56            if (last != null) {
57                table.put(c, entry.getValue() + table.get(last));
58            }
59            last = c;
60        }
61    }
62    static fastaRepeat(n : int, seq : String): int {
63        let seqi : int = 0;
64        let lenOut : int = 60;
65        let ret : int = 0;
66        while(n > 0)
67        {
68            if (n < lenOut) {
69                lenOut = n;
70            }
71            if (seqi + lenOut < seq.length()) {
72                ret += seq.substring(seqi, seqi + lenOut).length();
73                seqi += lenOut;
74            }
75            else {
76                let s : String = seq.substring(seqi);
77                seqi = lenOut - s.length();
78                ret += (s + seq.substring(0, seqi)).length();
79            }
80            n -= lenOut;
81        }
82        return ret;
83    }
84    static fastaRandom(n : int, table : HashMap<Char, Double>): int {
85        let line : char[] = new char[60];
86        makeCumulative(table);
87        let ret : int = 0;
88        while(n > 0)
89        {
90            if (n < line.length) {
91                line = new char[n];
92            }
93            for (let i : int = 0; i < line.length; i++) {
94                let r : double = Random.rand(1);
95                for (let entry : HashMap.Entry<Char, Double> of table.entrySet()){
96                    let c : Char = entry.getKey();
97                    if (r < entry.getValue()) {
98                        line[i] = c;
99                        break;
100                    }
101                }
102            }
103            ret += new String(line).length();
104            n -= line.length;
105        }
106        return ret;
107    }
108    count : int = 7;
109    static readonly expected : int = 1456000;
110    public  run(): void {
111        let ret : int = 0;
112        ret += fastaRepeat(2 * count * 100000, ALU);
113        ret += fastaRandom(3 * count * 1000, IUB);
114        ret += fastaRandom(5 * count * 1000, HomoSap);
115
116        assert ret == this.expected: "Incorrect result";
117    }
118}
119
120function main(): void {
121  let a = new StringFasta;
122  a.run();
123}
124
125/* @@? 41:12 Error SyntaxError: Local type declaration (class, struct, interface and enum) support is not yet implemented.  */
126