1/*
2 * Copyright (c) 2023 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
16class DeepProxy {
17    constructor(obj, handler) {
18        return new Proxy(obj, handler);
19    }
20}
21class ClassB {
22    constructor(n) {
23        this.n = 0;
24        this.n = n;
25    }
26}
27
28let nextFreeId = 0;
29class ClassA {
30    constructor(a, b) {
31        this.a = a;
32        this.b = new ClassB(b);
33        this.id = nextFreeId++;
34    }
35}
36
37// Testing the proxy situation.
38let data1 = [new ClassA(1, 10), new ClassA(3, 30), new ClassA(4, 40), new ClassA(2, 20), new ClassA(11, 250)];
39let objHandler1 = new DeepProxy(data1, {});
40print(JSON.stringify(objHandler1));
41objHandler1.sort((a, b) => {
42    return a.b.n - b.b.n;
43})
44print(JSON.stringify(objHandler1));
45
46// Testing cases with both proxy and hole.
47let data2 = [new ClassA(1, 10), , new ClassA(3, 30), , new ClassA(4, 40), new ClassA(2, 20), new ClassA(11, 250)];
48let objHandler2 = new DeepProxy(data2, {
49    deleteProperty(target, prop) {
50        print(`delete ${prop.toString()}`);
51        return Reflect.deleteProperty(target, prop);
52    }
53});
54objHandler2.sort((a, b) => {
55    return a.b.n - b.b.n;
56})
57print(JSON.stringify(objHandler2));
58
59/*
60 * Test Case Description:
61 * 1. This use case is used to verify the logical processing order of the binary insertion sorting algorithm.
62 * 2. If there are any changes to the use case, please confirm if the use case needs to be modified.
63 */
64let arr1 = [1, 3, 2];
65arr1.sort((a, b) => {
66    return a - b;
67});
68print(JSON.stringify(arr1));
69
70/*
71 * Test Case Description:
72 * 1. This use case is used to verify the logical processing order of the quick sorting algorithm.
73 * 2. If there are any changes to the use case, please confirm if the use case needs to be modified.
74 */
75for (let i = 0; i < 100; i++) {
76    arr1[i] = i;
77}
78arr1[0] = 99;
79arr1[99] = 0;
80arr1[49] = 50;
81arr1[50] = 49;
82arr1.sort((a, b) => {
83    return a - b;
84})
85print(JSON.stringify(arr1));
86
87// Modification of objects during the comparison process.
88let arr2 = [1, 3, 2];
89arr2.sort((a, b) => {
90    if (a == 1 || b == 1) {
91        arr2[0] == 2;
92    }
93    return a - b;
94});
95print(JSON.stringify(arr2));
96
97let arr3 = [1, 3, 2];
98arr3.sort((a, b) => {
99    if (a == 1 || b == 1) {
100        arr3[4] == 2;
101    }
102    return a - b;
103});
104print(JSON.stringify(arr3));
105
106// Testing the situation where this is an Object
107let obj1 = {0: 1, 1: 3, a: 6, 2: 2, length: 3};
108Array.prototype.sort.call(obj1, (a, b) => {
109    return a - b;
110});
111print(JSON.stringify(obj1));
112
113let obj2 = {0: 1, 1: 3, a: 6, 2: 2, length: 3};
114Array.prototype.sort.call(obj2, (a, b) => {
115    if (a == 1 || b == 1) {
116        obj2.a = 60;
117    }
118    return a - b;
119});
120print(obj2.a == 60);
121print(JSON.stringify(obj2));
122
123let obj3 = {0: 1, 1: 3, a: 6, 2: 2, length: 2};
124Array.prototype.sort.call(obj3, (a, b) => {
125    return a - b;
126});
127print(obj3[1] == 3)
128print(JSON.stringify(obj3));
129
130let obj4 = {0: 1, 1: 3, a: 6, 3: 2, length: 4};
131Array.prototype.sort.call(obj4, (a, b) => {
132    return a - b;
133});
134print(obj4[2] == 3)
135print(JSON.stringify(obj4));
136
137// Test if this is a Map type;
138let map1 = new Map();
139map1.set(0, 1);
140map1.set(1, 3);
141map1.set(2, 2);
142map1.set("a", 6);
143map1.set("length", 3);
144Array.prototype.sort.call(map1, (a, b) => {
145    return a - b;
146});
147print(JSON.stringify(map1));
148
149let map2 = new Map();
150map2.set(0, 1);
151map2.set(1, 3);
152map2.set(2, 2);
153map2.set("a", 6);
154map2.set("length", 3);
155Array.prototype.sort.call(map2, (a, b) => {
156    if (a == 1 || b == 1) {
157        map2.set("a", 60);
158    }
159    return a - b;
160});
161print(JSON.stringify(map2));
162
163// Test prototype
164let child1 = [1, 3, 2];
165let proto1 = [4, 7, 5];
166child1.__proto__ = proto1;
167child1.sort((a, b) => {
168    return a - b;
169});
170print(JSON.stringify(child1));
171
172let child2 = [1, , 2];
173child2.__proto__ = proto1;
174child2.sort((a, b) => {
175    return a - b;
176});
177print(child2.hasOwnProperty('1'));
178print(JSON.stringify(child2));
179
180let child3 = [1, 3, 2];
181let proto2 = [4, , 5];
182child3.__proto__ = proto2;
183child3.sort((a, b) => {
184    return a - b;
185});
186print(JSON.stringify(child3));
187
188let child4 = [1, , 2];
189child4.__proto__ = proto2;
190child4.sort((a, b) => {
191    return a - b;
192});
193print(child4.hasOwnProperty('2'));
194print(JSON.stringify(child4));
195
196var test1 = [-321, 65, 0, -3215, 653, 650, -3210, -2147483648, 2147483647];
197print(test1.sort());
198
199
200var arr4 = new Array(5);
201arr4[0] = 93;
202arr4[1] = 930;
203arr4[2] = -45;
204arr4[3] = 44;
205arr4[4] = 0;
206print(arr4.sort(function(a, b){
207    a--;
208    b--;
209    return b-a;
210}));
211
212var arr5 = [3, 1, 4];
213arr5.sort((a, b) => {
214    if (a == 1 || b == 1) {
215        arr5[0] = 6;
216    }
217    return a - b;
218});
219print(arr5);
220
221Object.defineProperty(Array.prototype, "tt", {
222    value:37,
223    writable:false,
224});
225
226var arr6 = new Array(5);
227arr6[0] = 93;
228arr6[2] = -45;
229arr6[3] = "djs";
230arr6[4] = 0;
231print(arr6.sort());
232
233var arr7 = [1];
234print(arr7.sort());
235
236var res1 = Array.prototype.sort.call("m", Uint8Array);
237print(res1);
238
239try {
240    Array.prototype.sort.call("mm", Uint8Array);
241} catch (e) {
242    print(e.name);
243}
244
245const o1 = {
246    ..."654"
247};
248const arr8 = [1, 2, 3];
249const o2 = {
250    __proto__: arr8,
251    ...o1
252};
253o2.sort();
254print(o2[0]);
255print(o2[1]);
256print(o2[2]);
257
258const bigint64_array = new BigInt64Array();
259const proxy = new Proxy([1, 2, 3], bigint64_array);
260try {
261    proxy.sort();
262} catch (e) {
263    print(e.name);
264}
265
266try {
267    const vSort = new Float64Array(Float64Array);
268    vSort.__proto__.sort();
269} catch (e) {
270    print(e.message);
271}
272
273const v4 = [1, 255];
274class C5 extends Int16Array{
275    toString(a7, a8, a9, a10) {
276        super.includes();
277    }
278}
279try {
280    const v12 = new C5();
281    v4.sort(C5.prototype.toString);
282} catch (e) {
283    print(e.message);
284}
285const items = [
286    { name: "Edward", value: 21 },
287    { name: "Sharpe", value: 37 },
288    { name: "And", value: 45 },
289    { name: "The", value: -12 },
290    { name: "Magnetic", value: 13 },
291    { name: "Zeros", value: 37 },
292  ];
293
294items.sort((a, b) => a.value - b.value);
295print(JSON.stringify(items));
296
297items.sort((a, b) => {
298    const nameA = a.name.toUpperCase();
299    const nameB = b.name.toUpperCase();
300    if (nameA < nameB) {
301      return -1;
302    }
303    if (nameA > nameB) {
304      return 1;
305    }
306    return 0;
307  });
308
309print(JSON.stringify(items));
310
311const numbers = [3, 1, 4, 1, 5];
312const sorted = numbers.sort((a, b) => a - b);
313sorted[0] = 10;
314print(numbers[0]); // 10
315
316const students = [
317    { name: "Alex", grade: 15 },
318    { name: "Devlin", grade: 15 },
319    { name: "Eagle", grade: 13 },
320    { name: "Sam", grade: 14 },
321];
322// stable
323students.sort((firstItem, secondItem) => firstItem.grade - secondItem.grade);
324print(JSON.stringify(students));
325const v2 =[];
326class C3{};
327v2.__proto__ = C3;
328let arr = new Array(518);
329for(let i=0;i<518;i++){
330    arr[i]=""+i;
331}
332arr[512]="valueOf";
333arr[513]="p0";
334arr[514]="p1";
335arr[515]="p2";
336arr[516]="p3";
337arr[517]="p4";
338arr.sort();
339
340//for cmp return type is double
341let arr34 = [2.63, 1.67];
342print(arr34.sort((a, b)=> a - b));
343print("sort Test Success!");
344
345// String toSorted
346{
347	let array1 = new Array();
348    for (let i = 0; i < 1; i++) array1[i] = `string.${i}`;
349    print(array1.toSorted());
350
351    array1 = new Array();
352    for (let i = 0; i < 2; i++) array1[i] = `string.${i}`;
353    print(array1.toSorted());
354
355    array1 = new Array();
356    for (let i = 0; i < 2; i++) array1[i] = `string.${1 - i}`;
357    print(array1.toSorted());
358
359    array1 = new Array();
360    array1[0] = `a`;
361    array1[1] = `b`;
362    array1[2] = `c`;
363    array1[3] = `d`;
364    array1[4] = `e`;
365    array1[5] = `f`;
366    array1[6] = `g`;
367    print(array1.toSorted());
368
369    array1 = new Array();
370    array1[6] = `a`;
371    array1[5] = `b`;
372    array1[4] = `c`;
373    array1[3] = `d`;
374    array1[2] = `e`;
375    array1[1] = `f`;
376    array1[0] = `g`;
377    print(array1.toSorted());
378}
379