/***********************************************************
* FileName         : down-git.js
* Description      : 깃허브 파일 다이렉트 다운로드
*
* Author           : (주)한국공학기술연구원
* Created Date     : 2021.12.13
* Modifide Date    : 2022.03.07
* Modified Content : 다운로드시 폴더명까지 파일이름으로 저장 기능 수정 downloadFile() 수정
* Reference        : 
***********************************************************/

var downGitModule = angular.module('downGitModule', []);

downGitModule.factory('downGitService', [
    '$http',
    '$q',    
    function ($http, $q) {
        var repoInfo = {};

        var parseInfo = function(parameters) {
            var repoPath = new URL(parameters.url).pathname;
            var splitPath = repoPath.split("/");
            var info = {};

            info.author = splitPath[1];
            info.repository = splitPath[2];
            info.branch = splitPath[4];

            info.rootName = splitPath[splitPath.length-1];
            if(!!splitPath[4]){
                info.resPath = repoPath.substring(
                    repoPath.indexOf(splitPath[4])+splitPath[4].length+1
                );
            }
            info.urlPrefix = "https://api.github.com/repos/"+
                info.author+"/"+info.repository+"/contents/";
            info.urlPostfix = "?ref="+info.branch;

            if(!parameters.fileName || parameters.fileName==""){
                info.downloadFileName = info.rootName;
            } else{
                info.downloadFileName = parameters.fileName;
            }

            if(parameters.rootDirectory=="false"){
                info.rootDirectoryName = "";

            } else if(!parameters.rootDirectory || parameters.rootDirectory=="" ||
                parameters.rootDirectory=="true"){
                info.rootDirectoryName = info.rootName+"/";

            } else{
                info.rootDirectoryName = parameters.rootDirectory+"/";
            }

            return info;
        }

        var downloadDir = function(progress){
            progress.isProcessing.val = true;

            var dirPaths = [];
            var files = [];
            var requestedPromises = [];

            dirPaths.push(repoInfo.resPath);
            mapFileAndDirectory(dirPaths, files, requestedPromises, progress);
        }

        var mapFileAndDirectory = function(dirPaths, files, requestedPromises, progress){
            $http.get(repoInfo.urlPrefix+dirPaths.pop()+repoInfo.urlPostfix).then(function(response) {
                if (response.status !== 404) {  // 24.10.04 : LTW : 유효한 응답일 때만 다운로드 수행
                    for(var i=response.data.length-1; i>=0; i--){
                        if(response.data[i].type=="dir"){
                            dirPaths.push(response.data[i].path);

                        } else{
                            if(response.data[i].download_url){
                                getFile(response.data[i].path,
                                    response.data[i].download_url,
                                    files, requestedPromises, progress
                                );
                            } else {
                                console.log(response.data[i]);
                            }
                        }
                    }
                } else {
                    alert('다운로드에 실패하였습니다. 채널톡 또는 고객센터에 문의를 남겨주세요');
                }

                if(dirPaths.length<=0){
                    downloadFiles(files, requestedPromises, progress);
                } else{
                    mapFileAndDirectory(dirPaths, files, requestedPromises, progress);
                }
            });
        }

        var downloadFiles = function(files, requestedPromises, progress){
            var zip = new JSZip();
            $q.all(requestedPromises).then(function(data) {
                for(var i=files.length-1; i>=0; i--){
                    zip.file(
                        repoInfo.rootDirectoryName+files[i].path.substring(decodeURI(repoInfo.resPath).length+1),
                        files[i].data
                    );
                }

                progress.isProcessing.val=false;
                zip.generateAsync({type:"blob"}).then(function(content) {
                    saveAs(content, repoInfo.downloadFileName+".zip");
                });
            });
        }

        var getFile = function (path, url, files, requestedPromises, progress) {
            var promise = $http.get(url, {responseType: "arraybuffer"}).then(function (file) {
                files.push({path:path, data:file.data});
                progress.downloadedFiles.val = files.length;
            }, function(error) {
                console.log(error);
            });

            requestedPromises.push(promise);
            progress.totalFiles.val = requestedPromises.length;
        }

        var downloadFile = function (url, progress, toastr) {

          var downloadUrl = "https://raw.githubusercontent.com/"+url.author+"/"+
                  url.repository+"/"+url.branch+"/"+url.resPath;
          fetch(downloadUrl)
          .then(response => {
            if (response.ok) { // 24.10.04 : LTW : 유효한 응답일 때만 다운로드 수행
                return response.blob();
            } else {
                throw new Error("File not found: " + downloadUrl);
            }
        })
           .then(blob => {
             const link = document.createElement("a");
             link.href = URL.createObjectURL(blob);

             //22.3.7 : LTW : 구분자 이용해서 폴더 제거 후 마지막 url의 이름을 파일명으로 사용
             var filenameUrl = url.resPath.split("/");
             //console.log(filenameUrl);
             //console.log(filenameUrl.length);
             //console.log(filenameUrl[filenameUrl.length-1]);
             //link.download = url.resPath;
             link.download = filenameUrl[filenameUrl.length-1];
             link.click();
         })
         .catch(error => {
            console.error(error);

            var filenameUrl = url.resPath.split("/");
             //console.log(filenameUrl);
             //console.log(filenameUrl.length);
             //console.log(filenameUrl[filenameUrl.length-1]);
             //link.download = url.resPath;
             
            toastr.warning("다운로드에 실패하였습니다. 채널톡 또는 고객센터에 문의를 남겨주세요\n\n 파일명 : " + filenameUrl[filenameUrl.length-1] + " \n 고객센터 : 061-721-2484", "다운로드 실패", 
                {
                    iconClass: 'toast-down',
                    escapeHtml: false,
                    timeOut: 0,             // 자동으로 사라지지 않음
                    extendedTimeOut: 0,     // 마우스를 올렸을 때 사라지지 않음
                    closeButton: true       // 닫기 버튼 추가

                });
            //alert('다운로드에 실패하였습니다. 채널톡 또는 고객센터에 문의를 남겨주세요');
            //toastr.warning("111.", {iconClass: 'toast-down'});
        });
          /*
            progress.isProcessing.val=true;
            progress.downloadedFiles.val = 0;
            progress.totalFiles.val = 1;

            var zip = new JSZip();
            $http.get(url, {responseType: "arraybuffer"}).then(function (file) {
                progress.downloadedFiles.val = 1;
                zip.file(repoInfo.rootName, file.data);

                progress.isProcessing.val=false;
                zip.generateAsync({type:"blob"}).then(function(content) {
                    saveAs(content, repoInfo.downloadFileName+".zip");
                });
            }, function(error) {
                console.log(error);
                progress.isProcessing.val=false;
                toastr.warning("Error! Server failure or wrong URL.", {iconClass: 'toast-down'});
            });
            */
        }

        return {
            downloadZippedFiles: function(parameters, progress, toastr) {
                repoInfo = parseInfo(parameters);

                if(!repoInfo.resPath || repoInfo.resPath==""){
                    if(!repoInfo.branch || repoInfo.branch==""){
                        repoInfo.branch="master";
                    }

                    var downloadUrl = "https://github.com/"+repoInfo.author+"/"+
                        repoInfo.repository+"/archive/"+repoInfo.branch+".zip";

                    window.location = downloadUrl;

                }else{
                    $http.get(repoInfo.urlPrefix+repoInfo.resPath+repoInfo.urlPostfix).then(function(response) {
                        if(response.data instanceof Array){
                          downloadDir(progress);
                        }else{
                          //downloadFile(response.data.download_url, progress, toastr);
                          downloadFile(repoInfo, progress, toastr);
                        }

                    }, function(error) {
                        //console.log("probable big file.");

                        downloadFile(repoInfo, progress, toastr);
                        /*
                        downloadFile("https://raw.githubusercontent.com/"+repoInfo.author+"/"+
                                repoInfo.repository+"/"+repoInfo.branch+"/"+repoInfo.resPath,
                                progress, toastr);
                        */
                    });
                }
            },
        };
    }
]);
