1 module tagion.tools.boot.stiefel;
2 
3 import std.array;
4 import std.file : exists;
5 import std.format;
6 import std.getopt;
7 import std.path;
8 import std.stdio;
9 import tagion.basic.Types : Buffer, FileExtension;
10 import tagion.basic.basic : isinit;
11 import tagion.basic.tagionexceptions;
12 import tagion.crypto.SecureNet;
13 import tagion.dart.Recorder;
14 import tagion.hibon.Document;
15 import tagion.hibon.HiBONFile : fread, fwrite;
16 import tagion.hibon.HiBONFile;
17 import tagion.script.TagionCurrency;
18 import tagion.script.common;
19 import tagion.script.standardnames;
20 import tagion.tools.Basic;
21 import tagion.tools.boot.genesis;
22 import tagion.tools.revision;
23 import tagion.utils.Term;
24 import tagion.hibon.BigNumber;
25 import tagion.hibon.HiBONRecord : isRecord;
26 
27 alias check = Check!TagionException;
28 
29 mixin Main!(_main, "tagionboot");
30 
31 int _main(string[] args) {
32     immutable program = args[0];
33     bool version_switch;
34     bool standard_output;
35     bool standard_input;
36     bool account;
37     string genesis;
38     bool trt;
39     string[] nodekeys;
40     string output_filename = "dart".setExtension(FileExtension.hibon);
41     const net = new StdHashNet;
42     try {
43         auto main_args = getopt(args,
44                 std.getopt.config.caseSensitive,
45                 std.getopt.config.bundling,
46                 "version", "display the version", &version_switch,
47                 "v|verbose", "Prints more debug information", &__verbose_switch, //"c|stdout", "Print to standard output", &standard_output,
48                 "o|output", format("Output filename : Default %s", output_filename), &output_filename, // //        "output_filename|o", format("Sets the output file name: default : %s", output_filenamename), &output_filenamename,
49                 "p|nodekey", "Node channel key(Pubkey) ", &nodekeys,
50                 "t|trt", "Generate a recorder from a list of bill files for the trt", &trt,
51                 "a|account", "Accumulates all bills in the input", &account, //         "bills|b", "Generate bills", &number_of_bills,
52                 "g|genesis", "Genesis document", &genesis,
53 
54                 // "value|V", format("Bill value : default: %d", value), &value,
55                 // "passphrase|P", format("Passphrase of the keypair : default: %s", passphrase), &passphrase
56                 //"initbills|b", "Testing mode", &initbills,
57                 //"nnc", "Initialize NetworkNameCard with given name", &nnc_name,
58         );
59 
60         if (version_switch) {
61             revision_text.writeln;
62             return 0;
63         }
64 
65         if (main_args.helpWanted) {
66             //       writeln(logo);
67             defaultGetoptPrinter(
68                     [
69                     //                format("%s version %s", program, REVNO),
70                     "Documentation: https://tagion.org/",
71                     "",
72                     "Usage:",
73                     format("%s [<option>...] <hibon-files> ...", program),
74                     "",
75                     "Where:",
76                     format("<file>           hibon outfile (Default %s)", output_filename),
77                     "",
78 
79                     "<option>:",
80 
81                     ].join("\n"),
82                     main_args.options);
83             return 0;
84         }
85         auto factory = RecordFactory(net);
86         auto recorder = factory.recorder;
87         standard_input = (args.length == 1);
88         standard_output = output_filename.empty;
89         if (standard_output) {
90             vout = stderr;
91         }
92         verbose("standard_input: %s, args %s", standard_input, args);
93         if (!nodekeys.empty && standard_input) {
94             auto fin = stdin;
95 
96 
97             BigNumber total;
98             long start_bills;
99             foreach(doc; HiBONRange(fin)) {
100                 if (doc.isRecord!TagionBill) {
101                     const bill = TagionBill(doc);
102                     total += bill.value.units;
103                     start_bills += 1;
104                     recorder.insert(bill, Archive.Type.ADD);
105                 }
106             }
107             TagionGlobals genesis_globals;
108             genesis_globals.total = total;
109             genesis_globals.total_burned = 0;
110             genesis_globals.number_of_bills = start_bills;
111             genesis_globals.burnt_bills = 0;
112             verbose("Total %s.%09sTGN", total / TagionCurrency.BASE_UNIT, total % TagionCurrency.BASE_UNIT);
113 
114             Document testamony;
115             if (genesis) {
116                 check(genesis.exists, format("File %s not found!", genesis));
117                 testamony = genesis.fread;
118             }
119             auto genesis_list = createGenesis(nodekeys, testamony, genesis_globals);
120             recorder.insert(genesis_list, Archive.Type.ADD);
121             TagionHead tagion_head;
122             tagion_head.name = TagionDomain;
123             tagion_head.current_epoch = 0;
124             recorder.add(tagion_head);
125         }
126         else if( standard_input && trt) {
127             auto fin = stdin;
128             TagionBill[] bills;
129             foreach(doc; HiBONRange(fin)) {
130                 if (doc.isRecord!TagionBill) {
131                     bills ~= TagionBill(doc);
132                 }
133             }
134             import tagion.trt.TRT;
135             genesisTRT(bills, recorder, net);
136         }
137         else {
138             foreach (file; args[1 .. $]) {
139                 check(file.exists, format("File %s not found!", file));
140 
141                 const doc = file.fread;
142                 recorder.add(doc);
143             }
144         }
145         if (standard_output) {
146             stdout.rawWrite(recorder.toDoc.serialize);
147             return 0;
148         }
149 
150         output_filename.fwrite(recorder);
151     }
152     catch (Exception e) {
153         error(e);
154         return 1;
155 
156     }
157     return 0;
158 }