/*Светофор
Используя асинхронную функцию и бесконечный цикл, просимулируйте светофор:

Для отображения включения того или иного света используйте один или три DOM-элемента.
Stage 2
Сделайте trafficLight более универсальной - добавьте в параметры DOM-элемент для отображения, а так же время работы каждого цвета
*/

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


async function trafficLight(element, ms){
    while (true){
        //включаем зеленый
        element.className = "svetoforGreen"
        await delay(ms)
        //включаем желтый
        element.className = "svetoforYellow"
        await delay(ms)
        //включаем красный
        element.className = "svetoforRed"
        await delay(ms)
    }
}

trafficLight(svetofor, 3000)

/*PedestrianTrafficLight
Напишите упрощенный светофор для пешеходов
Stage 2
Используя Promise.race, domEventPromise и кнопку в DOM сделайте пешеходный светофор с кнопкой, который так же переключается по времени периодически.
Stage 3
Не давайте возможности пешеходам сильно наглеть - предусмотрите задержку, после которой будет работать кнопка.*/
{
    function domEventPromise(element, eventName) {
        function executor(resolve) {
            //happy hacking
            function myEvent(event) {
                console.log('click')
                element.removeEventListener(eventName, myEvent)
                resolve(event)

            }


            element.addEventListener(eventName, myEvent)

        }
        return new Promise(executor)
    }



    async function PedestrianTrafficLight(element, ms) {
        while (true) {
            //включаем зеленый
            element.className = "svetoforGreen"
            await delay(ms)

            //включаем красный

            element.className = "svetoforRed"
            await delay(2000)
            await Promise.race([
                delay(ms - 2000),
                domEventPromise(padestrianSvetoforButton, 'click')
            ])
        }
    }

    PedestrianTrafficLight(padestrianSvetofor, 8000)


}

/* speedtest
Написать асинхронную функцию

async function speedtest(getPromise, count,parallel=1){
....
    return {
        duration,
        querySpeed, //средняя скорость одного запроса
        queryDuration, //
        parallelSpeed,
        parallelDuration
    }
}

speedtest(() => delay(1000), 10, 10 ).then(result => console.log(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)

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

    /*var timer = makeProfileTimer()
    alert('Замеряем время работы этого alert')
    alert(timer())*/





    async function speedtest(getPromise, count, parallel = 1) {

        let durationStart = makeProfileTimer() //засекаем время старта всего цикла (duration)

        for (let i = 0; i < count; i++) { // в этом цикле задаем количество повторов count
            let parallelArr = [] //тут будут храниться промисы
            for (let p = 0; p < parallel; p++) { //добавляем нужное количество промисов в массив для запуска теста с параллельно запущеніми промисами
                parallelArr.push(getPromise())
            }

            await Promise.all(parallelArr) // тут запускаем все промисы из одной паралели и ждем пока зарезолвятся все
        }

        let duration = durationStart() //записываем в duration разницу между точкой старта перед циклом и этой точкой 
        let parallelDuration = duration / (parallel * count)
        let querySpeed = (parallel * count) / duration
        let queryDuration = duration / count
        let parallelSpeed = (parallel * count) / duration

        ////
        return {
            duration,
            querySpeed, //средняя скорость одного запроса
            queryDuration, //
            parallelSpeed,
            parallelDuration
        }
    }

    speedtest(() => fetch('http://swapi.dev/api/people/1').then(res => res.json()), 10, 5).then(x => console.log(x))
}
  /*gql
Напишите функцию gql, которая осуществляет GraphQL запрос. Функция принимает три параметра:
Эндпоинт - адрес сервера. Например "http://shop-roles.node.ed.asmer.org.ua/graphql"
Текст запроса (query). Например:
query cats($q: String){
    CategoryFind(query: $q){
        _id name
    }
}

Параметры(переменные) (variables) запроса объектом. Например:
{
    q: "[{}]"
}
Функция должна возвращать промис, созданный fetch со следующими настройками:
Метод POST
Заголовки:
Content-Type - application/json
Accept- application/json
Тело - JSON, объект с двумя ключами - query (текст запроса) и variables
Проверьте вашу функцию:*/
{
    ;(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(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(token)
    })()


    async function gql(endpoint, myquery, variables) {
        let result = await fetch(endpoint, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json;charset=utf-8',
                'Accept': 'application/json'
            },
            body: JSON.stringify({
                query: myquery,
                variables: variables
            })
        }).then(res => res.json())

        return result

    }
}

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

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

function jwtDecode(token) {
    let result;
    try {
      let secondPartToken = token.split('.')[1];
      result = JSON.parse(atob(secondPartToken));
    } catch (e) {
    }

    return result;
  }

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