/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

"use strict";

const helpers = require("./helpers");
const ttypes = require(`./${helpers.genPath}/ThriftTest_types`);
const Int64 = require("node-int64");

//all Languages in UTF-8
/*jshint -W100 */
const stringTest = (module.exports.stringTest =
  "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, " +
  "Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, " +
  "Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, " +
  "বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, " +
  "Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, " +
  "Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, " +
  "Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, " +
  "Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, " +
  "Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski, " +
  "Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia, " +
  "Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa, " +
  "ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар, " +
  "Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, " +
  "Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa " +
  "Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, مازِرونی, Bahasa " +
  "Melayu, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪" +
  "Norsk (nynorsk)‬, ‪Norsk (bokmål)‬, Nouormand, Diné bizaad, " +
  "Occitan, Иронау, Papiamentu, Deitsch, Polski, پنجابی, پښتو, " +
  "Norfuk / Pitkern, Português, Runa Simi, Rumantsch, Romani, Română, " +
  "Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple " +
  "English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk, " +
  "Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog, " +
  "Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, " +
  "Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, " +
  "Bân-lâm-gú, 粵語");
/*jshint +W100 */

const specialCharacters = (module.exports.specialCharacters =
  'quote: " backslash:' +
  " forwardslash-escaped: / " +
  " backspace: \b formfeed: \f newline: \n return: \r tab: " +
  ' now-all-of-them-together: "\\/\b\n\r\t' +
  " now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><" +
  ' char-to-test-json-parsing: ]] "]] \\" }}}{ [[[ ');

const mapTestInput = (module.exports.mapTestInput = {
  a: "123",
  "a b": "with spaces ",
  same: "same",
  "0": "numeric key",
  longValue: stringTest,
  stringTest: "long key"
});

const simple = [
  ["testVoid", undefined],
  ["testString", "Test"],
  ["testString", ""],
  ["testString", stringTest],
  ["testString", specialCharacters],
  ["testBool", true],
  ["testBool", false],
  ["testByte", 1],
  ["testByte", 0],
  ["testByte", -1],
  ["testByte", -127],
  ["testI32", -1],
  ["testDouble", -5.2098523],
  ["testDouble", 7.012052175215044],
  ["testEnum", ttypes.Numberz.ONE],
  ["testI64", 5],
  ["testI64", -5],
  ["testI64", 734359738368],
  ["testI64", -734359738368],
  ["testI64", new Int64(new Buffer([0, 0x20, 0, 0, 0, 0, 0, 1]))], // 2^53+1
  [
    "testI64",
    new Int64(new Buffer([0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]))
  ], // -2^53-1
  ["testTypedef", 69]
];

const mapout = {};
for (let i = 0; i < 5; ++i) {
  mapout[i] = i - 10;
}

const deep = [
  [
    "testList",
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
  ]
];

const deepUnordered = [
  ["testMap", mapout],
  ["testSet", [1, 2, 3]],
  ["testStringMap", mapTestInput]
];

const out = new ttypes.Xtruct({
  string_thing: "Zero",
  byte_thing: 1,
  i32_thing: -3,
  i64_thing: 1000000
});

const out2 = new ttypes.Xtruct2();
out2.byte_thing = 1;
out2.struct_thing = out;
out2.i32_thing = 5;

const crazy = new ttypes.Insanity({
  userMap: { "5": 5, "8": 8 },
  xtructs: [
    new ttypes.Xtruct({
      string_thing: "Goodbye4",
      byte_thing: 4,
      i32_thing: 4,
      i64_thing: 4
    }),
    new ttypes.Xtruct({
      string_thing: "Hello2",
      byte_thing: 2,
      i32_thing: 2,
      i64_thing: 2
    })
  ]
});

const crazy2 = new ttypes.Insanity({
  userMap: { "5": 5, "8": 8 },
  xtructs: [
    {
      string_thing: "Goodbye4",
      byte_thing: 4,
      i32_thing: 4,
      i64_thing: 4
    },
    {
      string_thing: "Hello2",
      byte_thing: 2,
      i32_thing: 2,
      i64_thing: 2
    }
  ]
});

const insanity = {
  "1": { "2": crazy, "3": crazy },
  "2": { "6": { userMap: {}, xtructs: [] } }
};

module.exports.simple = simple;
module.exports.deep = deep;
module.exports.deepUnordered = deepUnordered;

module.exports.out = out;
module.exports.out2 = out2;
module.exports.crazy = crazy;
module.exports.crazy2 = crazy2;
module.exports.insanity = insanity;
