1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3#
4# Copyright (c) 2024 Huawei Device Co., Ltd.
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import argparse
18import os
19import shutil
20import subprocess
21import time
22
23
24def parse_args():
25    parser = argparse.ArgumentParser(description="Generate and verify ABC files.")
26    parser.add_argument(
27        "--es2abc-dir", required=True, help="Path to the es2abc directory.")
28    parser.add_argument(
29        "--verifier-dir", required=True, help="Path to the ark_verifier directory.")
30    parser.add_argument(
31        "--js-ts-dir", required=False, help="Path to the directory containing .js and .ts files.")
32    parser.add_argument(
33        "--keep-files", action="store_true", help="Keep generated files after verification.")
34    return parser.parse_args()
35
36
37def find_files(root_dir, extensions):
38    for root, _, files in os.walk(root_dir):
39        for file in files:
40            if file.endswith(extensions):
41                yield os.path.join(root, file)
42
43
44def copy_files(src_dir, dest_dir, extensions):
45    if not os.path.exists(dest_dir):
46        os.makedirs(dest_dir)
47
48    for file_path in find_files(src_dir, extensions):
49        dest_path = os.path.join(dest_dir, os.path.basename(file_path))
50        shutil.copy(file_path, dest_path)
51
52
53def setup_directories(script_dir):
54    temp_files_dir = os.path.join(script_dir, "temp_files")
55    temp_js_ts_dir = os.path.join(temp_files_dir, "temp_js_ts")
56    temp_abc_dir = os.path.join(temp_files_dir, "temp_abc")
57
58    if os.path.exists(temp_files_dir):
59        shutil.rmtree(temp_files_dir)
60
61    os.makedirs(temp_js_ts_dir, exist_ok=True)
62    os.makedirs(temp_abc_dir, exist_ok=True)
63
64    return temp_files_dir, temp_js_ts_dir, temp_abc_dir
65
66
67def process_file(file_path, es2abc_path, temp_abc_dir, verifier_dir):
68    base_name = os.path.splitext(os.path.basename(file_path))[0]
69    abc_filename = f"{base_name}.abc"
70    abc_output_path = os.path.join(temp_abc_dir, abc_filename)
71    es2abc_command = [es2abc_path, "--module", file_path, "--output", abc_output_path]
72
73    stdout, stderr, returncode = run_command(es2abc_command)
74    if returncode != 0:
75        print(f"Ignored {file_path} (Failed to generate ABC)")
76        return False, True
77
78    verifier_command = [os.path.join(verifier_dir, "ark_verifier"), "--input_file", abc_output_path]
79    stdout, stderr, returncode = run_command(verifier_command)
80    if returncode == 0:
81        return True, False
82    else:
83        print(f"Verification failed for {abc_output_path}:\n{stderr}")
84        return False, False
85
86
87def run_command(command):
88    result = subprocess.run(command, capture_output=True, text=True)
89    return result.stdout, result.stderr, result.returncode
90
91
92def report_results(total, passed, failed, ignored, start_time):
93    end_time = time.time()
94    duration = end_time - start_time
95    completion_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(end_time))
96
97    print(f"Total JS/TS files: {total}")
98    print(f"Ignored JS/TS files: {ignored}")
99    print(f"Passed: {passed}")
100    print(f"Failed: {failed}")
101    print(f"Execution time: {duration:.2f} seconds")
102    print(f"Completion time: {completion_time}")
103
104
105def main():
106    start_time = time.time()
107    args = parse_args()
108
109    script_dir = os.path.dirname(os.path.abspath(__file__))
110    temp_files_dir, temp_js_ts_dir, temp_abc_dir = setup_directories(script_dir)
111
112    js_ts_dir = args.js_ts_dir if args.js_ts_dir else os.path.join(script_dir, "../../../ets_frontend/es2panda/test/")
113    copy_files(js_ts_dir, temp_js_ts_dir, (".js", ".ts"))
114
115    total = 0
116    passed = 0
117    failed = 0
118    ignored = 0
119
120    js_ts_files = list(find_files(temp_js_ts_dir, (".js", ".ts")))
121    es2abc_path = os.path.join(args.es2abc_dir, "es2abc")
122
123    for file_path in js_ts_files:
124        total += 1
125        success, ignore = process_file(file_path, es2abc_path, temp_abc_dir, args.verifier_dir)
126        if ignore:
127            ignored += 1
128        elif success:
129            passed += 1
130        else:
131            failed += 1
132
133    if not args.keep_files:
134        if os.path.isdir(temp_files_dir):
135            shutil.rmtree(temp_files_dir)
136            print(f"\n'{temp_files_dir}' directory has been deleted.")
137
138    report_results(total, passed, failed, ignored, start_time)
139
140
141if __name__ == "__main__":
142    main()
143