// Команда CLI: tools

Перем МаксимальнаяВложенность;
Перем ИскомыйПараметр;

#Область СлужебныйПрограммныйИнтерфейс

// Разложить JSON на параметры
// Показывает значения, которые можно получить из переданного JSON и возвращает
// конкретное значение при указании имени поля
// 
// Параметры:
//  JSON                           - Строка  - JSON данные                                                          - json
//  МаксимальныйУровеньВложенности - Число   - Ограничение на ур. вложенности разбора. На всю глубину по умолчанию  - nesting
//  ИмяПараметра                   - Строка  - Имя поля для получения. Выводит весь список, если не указано         - name 
//  Кодировка                      - Строка  - Кодировка, в которой записаны JSON данные                            - enc
// 
// Возвращаемое значение:
//  Строка - пустая строка
Функция РазложитьJSON(Знач JSON
	, Знач МаксимальныйУровеньВложенности = 0
	, Знач ИмяПараметра = ""
	, Знач Кодировка = "UTF-8") Экспорт

	МаксимальнаяВложенность = Число(МаксимальныйУровеньВложенности);
    ИскомыйПараметр         = ИмяПараметра;

	ПолучитьКоллекцию(JSON, Кодировка);

	Если Не ТипЗнч(JSON) = Тип("Соответствие") Тогда
		ВызватьИсключение "Ошибка преобразовани данных параметра JSON";
	КонецЕсли;

	Значение = ПолучитьЗначенияРекурсивно(JSON);
	Возврат Значение;

КонецФункции

// Преобразует файл с Base64 строкой в бинарный
// Преобразует файл с Base64 строкой в бинарный файл
// 
// Параметры:
//  Вход  - Строка  - Файл с Base64       - in
// 
// Возвращаемое значение:
//  Строка - пустая строка
Функция ПреобразоватьBase64ВДвоичные(Знач Вход) Экспорт

	ВходнойФайл = Новый Файл(Вход);

	Если Не ВходнойФайл.Существует() Тогда
		ВызватьИсключение("Не найден входной файл!");
	КонецЕсли;

	ТекстовыйДокумент = Новый ТекстовыйДокумент();
	ТекстовыйДокумент.Прочитать(Вход);
	
	B64 = ТекстовыйДокумент.ПолучитьТекст();
    ДД  = Base64Значение(B64);

	Возврат ДД;

КонецФункции

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Функция ПолучитьЗначенияРекурсивно(Знач JSON, Знач Префикс = "", Знач ТекущаяВложенность = 1, СоответствиеПолей = "")

	Если Не ЗначениеЗаполнено(СоответствиеПолей) Тогда
		СоответствиеПолей = Новый Соответствие;
	КонецЕсли;

	ВозвращаемоеЗначение = "";

	Для Каждого Пара Из JSON Цикл

		Значение = Пара.Значение;
		Ключ     = Префикс + Строка(Пара.Ключ);

		ЭтоКоллекция = ТипЗнч(Значение) = Тип("Соответствие") Или ТипЗнч(Значение) = Тип("Структура");
		СледующаяВложенность         = ТекущаяВложенность + 1;
		СледующаяВложенностьДоступна = МаксимальнаяВложенность = 0 Или СледующаяВложенность <= МаксимальнаяВложенность;

	    Если Не ЭтоКоллекция Или Не СледующаяВложенностьДоступна Тогда

			Дублирования = СоответствиеПолей.Получить(Ключ);

			Если Дублирования = Неопределено Тогда
				Счетчик         = 0;
				ПеременнаяСреды = Ключ;
			Иначе
				Счетчик         = Дублирования + 1;
				ПеременнаяСреды = Ключ + СтрЗаменить(Строка(Дублирования), Символы.НПП, "");
			КонецЕсли;

			СоответствиеПолей.Вставить(Ключ, Счетчик);

			ПолучитьСтроку(Значение);

			Если Не ЗначениеЗаполнено(ИскомыйПараметр) Тогда
			    Сообщить(ПеременнаяСреды, СтатусСообщения.Информация);
				Сообщить(Значение + Символы.ПС, СтатусСообщения.Внимание);
			Иначе

                Если ПеременнаяСреды = ИскомыйПараметр Тогда
					ВозвращаемоеЗначение = Значение;
					Прервать;
				КонецЕсли;

			КонецЕсли;	
		Иначе
			НовыйПрефикс = Ключ + "_";
			ВозвращаемоеЗначение = ПолучитьЗначенияРекурсивно(Значение
			    , НовыйПрефикс
				, СледующаяВложенность
				, СоответствиеПолей);

			Если ЗначениеЗаполнено(ВозвращаемоеЗначение) Тогда
				Прервать;
			КонецЕсли;

		КонецЕсли;

	КонецЦикла;

	Возврат ?(ЗначениеЗаполнено(ВозвращаемоеЗначение), ВозвращаемоеЗначение, Символы.ПС);

КонецФункции

Процедура ПолучитьСтроку(Значение)

	ЭтоКоллекция = ТипЗнч(Значение) = Тип("Соответствие") Или ТипЗнч(Значение) = Тип("Структура") Или ТипЗнч(Значение) = Тип("Массив");

	Если ЭтоКоллекция Тогда

		ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Windows
        , " "
        , Истина
        , Истина
        , Ложь
        , Ложь
        , Ложь
        , Ложь);

        ЗаписьJSON = Новый ЗаписьJSON;
        ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
    
        ЗаписатьJSON(ЗаписьJSON, Значение);
        Значение = ЗаписьJSON.Закрыть();

	Иначе
		Значение = Строка(Значение);
	КонецЕсли;

КонецПроцедуры

Процедура ПолучитьКоллекцию(Значение, Знач Кодировка)
    
    Если Значение = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
	ИсходноеЗначение = Значение;
	
	Если ЭтоКоллекция(Значение) Тогда
		Возврат;
	Иначе
		
		Если ТипЗнч(Значение) = Тип("ДвоичныеДанные") Тогда
			Значение = ПолучитьСтрокуИзДвоичныхДанных(Значение, Кодировка);
		Иначе
			Значение = Строка(Значение);
		КонецЕсли;
		
		Файл               = Новый Файл(Значение);
		ТекстовыйДокумент  = Новый ТекстовыйДокумент();
		
		Если Файл.Существует() Тогда
			
			ТекстовыйДокумент.Прочитать(Значение, Кодировка);
			Значение = ТекстовыйДокумент.ПолучитьТекст();
			
		ИначеЕсли СтрНачинаетсяС(нРег(Значение), "http") Тогда
			
			ИВФ = ПолучитьИмяВременногоФайла();
			КопироватьФайл(Значение, ИВФ);
			ТекстовыйДокумент.Прочитать(ИВФ, Кодировка);

			Значение = ТекстовыйДокумент.ПолучитьТекст();
			
			УдалитьФайлы(ИВФ);
			
		Иначе
			
			Значение = Строка(Значение);
			
		КонецЕсли;
			
	КонецЕсли;

	НормализоватьТекстовыйВвод(Значение);
	ЧтениеJSON  = Новый ЧтениеJSON;
	ЧтениеJSON.УстановитьСтроку(СокрЛП(Значение));
	Значение = ПрочитатьJSON(ЧтениеJSON, Истина, Неопределено, ФорматДатыJSON.ISO);
	ЧтениеJSON.Закрыть();
        
КонецПроцедуры

Процедура НормализоватьТекстовыйВвод(Текст)

	НачальнаяФигурная    = СтрНайти(Текст, "{");
	ПоследняяФигурная    = СтрНайти(Текст, "}", НаправлениеПоиска.СКонца);

	Если НачальнаяФигурная = 0 Или ПоследняяФигурная = 0 Тогда
		Возврат;
	КонецЕсли;

	Текст = Сред(Текст, НачальнаяФигурная, ПоследняяФигурная - НачальнаяФигурная + 1);

КонецПроцедуры

Функция ЭтоКоллекция(Знач Значение)

	Возврат ТипЗнч(Значение) = Тип("Массив")
			Или ТипЗнч(Значение) = Тип("Структура")
			Или ТипЗнч(Значение) = Тип("Соответствие");
			
КонецФункции 

#КонецОбласти