// speedtest
// Написать асинхронную функцию, где:
//      count - количество повторов
//      parallel - количество одновременных запросов / промисов в одном повторе
//      getPromise - функция, которая умеет вернуть нужный Вам промис для тестирования скорости его работы
// которая будет в цикле count раз создавать parallel промисов с помощью переданной функции getPromise, дожидаться выполнения всех parallel промисов, после чего цикл повторяется.
// Замерить время общее время выполнения, и вычислить:
//      duration, общую длительность работы цикла
//      parallelDuration, среднее время обработки запроса параллельно(за какое время исполнилось parallel * count промисов),
//      paralledSpeed, скорость в запросах в миллисекунду
//      queryDuration, реальное среднее время запроса(отталкиваясь от count и времени работы цикла).
//      querySpeed, реальное средняя скорость запроса
// Эти переменные вернуть в одном объекте - результате(см.заготовку выше)
// Для отладки попробуйте на delay(пример выше есть, реальное время будет отличаться на единицы - десятки миллисекунд).Потом можете попробовать на swapi.dev.Не создавайте чрезмерно много параллельных запросов.
{
    async function speedtest(getPromise, count, parallel = 1) {

        const start = performance.now()
        let promiseArr = []

        for (let i = 0; i < count; i++) {
            for (let j = 0; j < parallel; j++) {
                promiseArr.push(getPromise())
            }
            await Promise.all(promiseArr)
        }

        const end = performance.now()

        const duration = +(end - start).toFixed(5)
        const querySpeed = +(count / duration).toFixed(5)
        const queryDuration = +(duration / count).toFixed(5)
        const paralledSpeed = +((count * parallel) / duration).toFixed(5)
        const parallelDuration = +(duration / (count * parallel)).toFixed(5)

        return {
            duration,
            querySpeed,
            queryDuration,
            paralledSpeed,
            parallelDuration
        }
    }

    const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms))

    // Проверка
    speedtest(() => delay(1000), 10, 10).then(result => console.log('delay: ', result))
    // {duration: 10000, 
    // querySpeed: 0.001, //1 тысячная запроса за миллисекунду
    // queryDuration: 1000, //1000 миллисекунд на один реальный запрос в среднем 
    // parallelSpeed: 0.01  // 100 запросов за 10000 миллисекунд
    // parallelDuration: 100 // 100 запросов за 10000 миллисекунд
    speedtest(() => fetch('http://swapi.dev/api/people/1').then(res => res.json()), 10, 5).then(result => console.log('swapi: ', result))
}



// gql
// Напишите функцию gql, которая осуществляет GraphQL запрос. Функция принимает три параметра:
//     1. Эндпоинт - адрес сервера.Например "http://shop-roles.node.ed.asmer.org.ua/graphql"
//     2. Текст запроса(query).Например:
// query cats($q: String){
//     CategoryFind(query: $q){
//         _id name
//     }
// }
//      3. Параметры(переменные)(variables) запроса объектом.Например:
// {
//     q: "[{}]"
// }
// Функция должна возвращать промис, созданный fetch со следующими настройками:
//      Метод POST
//      Заголовки:
//          Content - Type - application / json
//          Accept - application / json
//      Тело - JSON, объект с двумя ключами - query(текст запроса) и variables

{
    const gql = function (url, query, variables) {
        let gqlParams = {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                Accept: 'application/json'
            },
            body: JSON.stringify(
                {
                    query,
                    variables
                }
            )
        }

        return fetch(url, gqlParams).then(res => res.json())
    };

    // проверка
    (async () => {
        const catQuery = `query cats($q: String){
                                CategoryFind(query: $q){
                                    _id name
                                }
                            }`
        const cats = await gql("http://shop-roles.node.ed.asmer.org.ua/graphql", catQuery, { q: "[{}]" })
        console.log(1, cats) //список категорий с _id name и всем таким прочим


        const loginQuery = `query login($login:String, $password:String){
                        login(login:$login, password:$password)
                }`

        const token = await gql("http://shop-roles.node.ed.asmer.org.ua/graphql", loginQuery, { login: "test457", password: "123123" })
        console.log(2, token)
    })()
}



// jwtDecode
// Напишете функцию jwtDecode, которая принимает единственный параметр token и возвращает информацию из переданного JWT токена.
// Алгоритм раскодирования:
// Разбить токен на три части.Разделитель - . (точка)
// Выделить среднюю часть.
// Используя функцию atob раскодировать среднюю часть из кодировки Base64, получив JSON
// Раскодировать JSON
// Вернуть раскодированные данные из JSON
// Учтите, что в качестве токена может быть передана какая - то дичь.В таком случае раскодировка не получится, и функция:
// Не должна сыпать красными матюками(ошибками) в консоль
// Должна просто вернуть undefined
{
    const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOnsiaWQiOiI2MzIyMDVhZWI3NGUxZjVmMmVjMWEzMjAiLCJsb2dpbiI6InRlc3Q0NTciLCJhY2wiOlsiNjMyMjA1YWViNzRlMWY1ZjJlYzFhMzIwIiwidXNlciJdfSwiaWF0IjoxNjY4MjcyMTYzfQ.rxV1ki9G6LjT2IPWcqkMeTi_1K9sb3Si8vLB6UDAGdw"

    const jwtDecode = function (token) {
        try {
            let parseData = token.split('.')[1]
            return JSON.parse(atob(parseData))
        }
        catch (e) {
            return undefined
        }
    }

    console.log(jwtDecode(token))
    //{
    //  "sub": {
    //    "id": "632205aeb74e1f5f2ec1a320",
    //    "login": "test457",
    //    "acl": [
    //      "632205aeb74e1f5f2ec1a320",
    //      "user"
    //    ]
    //  },
    //  "iat": 1668272163
    //}

    try {
        console.log(jwtDecode())         //undefined
        console.log(jwtDecode("дичь"))   //undefined
        console.log(jwtDecode("ey.ey.ey"))   //undefined

        console.log('до сюда доработало, а значит jwtDecode не матерился в консоль красным цветом')
    }
    finally {
        console.log('ДЗ, видимо, окончено')
    }
}