#!/bin/bash

# 发生错误也要继续执行
# set -e
set -u

logDir=/opt/compatibility_layer/logs
logFile=$logDir/buildCompatibilityEnv.log

if [ ! -d $logDir ]; then
    mkdir -p $logDir
    touch $logFile
elif [ ! -f $logFile ]; then
    touch $logFile
fi

echo $(date) >$logFile
echo -e "DEBUG - buildCompatibilityEnv 开始执行\n\n" >>$logFile

configDir=/opt/compatibility_layer/config
configFile=$configDir/configure.ini
installList=$configDir/install.list

if [ ! -d $configDir ]; then
    mkdir -m 755 -p $configDir
    touch $configFile $installList
    chmod 664 $configFile $installList
elif [ ! -f $configFile ]; then
    touch $configFile
    chmod 664 $configFile
elif [ ! -f $installList ]; then
    touch $installList
    chmod 664 $installList
fi

function upgradeFun() {
    echo "DEBUG - 升级场景" >>$logFile
    # 内存载入兼容层GSettings组件
    echo -e "DEBUG - 内存载入兼容层GSettings配置文件" >>$logFile
    glib-compile-schemas /usr/share/glib-2.0/schemas/ >>$logFile 2>&1
    if [ $? -ne 0 ]; then
        echo "ERROR - 内存载入兼容层GSettings配置文件失败" >>$logFile
    else
        echo "DEBUG - 内存载入兼容层GSettings配置文件成功" >>$logFile
    fi

    # docker相关
    # 创建docker工作空间
    echo -e "\n\nDEBUG - 创建容器镜像空间" >>$logFile
    resourcePre="fs.old-"
    resourceList=$(find / -maxdepth 1 -type d -name "$resourcePre*")

    [ -z "$resourceList" ] && echo "DEBUG - 不存在基础环境目录,程序退出" | tee -a $logFile && exit 0

    for resourceDir in $resourceList; do
        resourcePost=${resourceDir##*-}
        docker_ws=/opt/compatibility_layer/image_upgrade
        [ "$resourcePost" = "/fs.old" ] || [ -z "$resourcePost" ] && resourcePost="v10"
        docker_ws+="$resourcePost"

        if [ -d $docker_ws ]; then
            rm -rf $docker_ws/*
        else
            mkdir -p $docker_ws
        fi
        # 创建Dockerfile文件
        echo "DEBUG - 创建Dockerfile文件" >>$logFile
        echo "FROM scratch" >$docker_ws/Dockerfile

        # 补充Dockerfile文件 - 环境变量
        echo -e "ENV  DISPLAY=:0 \\ \n\t LANG=zh_CN.UTF-8 \\ \n\t GTK_IM_MODULE=fcitx \\ \n\t QT4_IM_MODULE=fcitx \\
     \t XMODIFIERS=@im=fcitx \\ \n\t CLUTTER_IM_MODULE=fcitx \\ \n\t QT_IM_MODULE=fcitx" >>$docker_ws/Dockerfile

        # 补充Dockerfile文件 - 其他信息
        echo "USER 1000" >>$docker_ws/Dockerfile
        echo 'CMD ["/bin/bash"]' >>$docker_ws/Dockerfile

        # 构建Docker镜像
        dockerIsoName="fsimage_""$resourcePost"

        echo "DEBUG - 开始制作Docker镜像$dockerIsoName..." >>$logFile
        docker build -t $dockerIsoName $docker_ws >>$logFile 2>&1
        if [ $? -eq 0 ]; then
            echo "DEBUG - $dockerIsoName镜像构建成功" >>$logFile
        else
            echo "ERROR - $dockerIsoName镜像构建失败" >>$logFile
        fi
    done
    # 修改Desktop文件
    # scriptName="/bin/bash /usr/bin/runWithCompatibility.sh"
    scriptName="kare run"
    echo -e "\n\nDEBUG - 开始修改Desktop文件..." >>$logFile
    desktopFileList=""
    for eachSubDir in $resourceList; do
        desktopFileList="${desktopFileList}${eachSubDir}/var/cache/RevisionsManager/compat-desktops "
    done
    desktopFileList="${desktopFileList}/usr/share/kylin-os-manager/replacement/desktop.list"
    for desktopFile in $desktopFileList; do
        if [ -f "$desktopFile" ]; then
            echo "DEBUG - 开始扫描Desktop文件..." >>$logFile
            # 存在多个desktop文件迁移成功
            cat $desktopFile | while read line; do
                # 处理每一个应用的desktop文件
                echo "DEBUG - 开始处理文件 "$line >>$logFile
                # bug #196176 【系统还原】还原回老V10后设置迁移的第三应用无法打开
                result=$(find /usr/share /home/ /etc/ -type f -name "$line" 2>>$logFile)
                # 每一个应用desktop文件存在多个路径
                echo "DEBUG - $line 文件扫描结果: "$result >>$logFile
                # 修改每个路径中的desktop文件
                for eachReault in $result; do
                    echo "DEBUG - 开始处理目标子文件 $eachReault" >>$logFile
                    # 判断是否是软链接，如果是，则跳过该子文件
                    if [ -L "$eachReault" ]; then
                        echo "WARNING - 子文件 $eachReault 是软链接文件，跳过该文件" >>$logFile
                        continue
                    fi
                    # 判断查找到的内容是否合法
                    if [[ $eachReault != *"desktop" ]]; then
                        echo "WARNING - 子文件 $eachReault 不合法，跳过该文件" >>$logFile
                        continue
                    fi
                    # bug #196014 因桌面desktop有问题因此无法双击引起的应用无法打开
                    echo "DEBUG - 处理TryExec|Path字段" >>$logFile
                    sed -i "s|^TryExec=|#TryExec=|" $eachReault >>$logFile 2>&1
                    # bug #196017 因桌面desktop有问题因此无法双击引起的应用无法打开
                    sed -i "s|^Path=|#Path=|" $eachReault >>$logFile 2>&1
                    judge=$(grep -m 1 '^Exec=' $eachReault | sed 's/^Exec=//' | awk -F " " '{print $1 $2}')
                    if [ "$judge" = "/bin/bash/usr/bin/runWithCompatibility.sh" ]; then
                        echo "DEBUG - $eachReault 已经被修改为兼容启动命令，本次不做修改" >>$logFile
                    elif [ "$judge" = "karerun" ]; then
                        echo "DEBUG - $eachReault 已经被修改为兼容启动命令，本次不做修改" >>$logFile
                    else
                        sed -i "s|^Exec=|Exec=$scriptName |" $eachReault >>$logFile 2>&1
                        if [ $? -ne 0 ]; then
                            echo "ERROR - $eachReault 子文件修改失败" >>$logFile
                        else
                            echo "DEBUG - $eachReault 子文件修改成功" >>$logFile
                        fi
                    fi
                done
            done
        else
            echo "ERROR - $desktopFile 文件路径不存在" >>$logFile
        fi
    done

    echo "DEBUG - 开始迁移原系统中的服务" >>$logFile

    for resourceDir in $resourceList; do

        serviceSrcDir="$resourceDir/usr/share/dbus-1/services"
        serviceDstDir="/usr/share/dbus-1/services"
        serviceRootDir="/opt/compatibility_layer/services/"

        resourcePost=${resourceDir##*-}
        [ "$resourcePost" = "/fs.old" ] || [ -z "$resourcePost" ] && resourcePost="v10"
        serviceSubDir="${serviceRootDir}${resourcePost}"

        echo "DEBUG - 服务迁移目录为$serviceSubDir" >>$logFile

        if [ -d $serviceSubDir ]; then
            rm -rf $serviceSubDir/*
        else
            mkdir -p $serviceSubDir
        fi

        [ -f "$serviceSrcDir" ] && ls $serviceSrcDir >${serviceRootDir}services-${resourcePost}transfer.list

        if [ -f ${serviceRootDir}services-${resourcePost}.list ] && [ -f ${serviceRootDir}services-${resourcePost}transfer.list ]; then
            diff ${serviceRootDir}services-${resourcePost}.list ${serviceRootDir}services-${resourcePost}transfer.list |
                awk -F "> " '/^> /{print $2}' | while read eachSrv; do
                echo "DEBUG - 迁移服务$eachSrv" >>$logFile
                if [ -f $serviceSrcDir/$eachSrv ]; then
                    cp -p $serviceSrcDir/$eachSrv $serviceSubDir/$eachSrv
                    if [ $? -ne 0 ]; then
                        echo "ERROR - $serviceSrcDir/$eachSrv迁移失败" >>$logFile
                        continue
                    fi
                    sed -i "s|^Exec=|Exec=$scriptName |" $serviceSubDir/$eachSrv >>$logFile 2>&1
                    cp -p $serviceSubDir/$eachSrv $serviceDstDir/$eachSrv
                    if [ $? -ne 0 ]; then
                        echo "ERROR - $serviceSrcDir/$eachSrv迁移失败" >>$logFile
                        continue
                    fi
                else
                    echo "ERROR - 服务文件${serviceSrcDir}/${eachSrv}不存在,无法迁移旧系统服务，对于少部分应用存在影响" >>$logFile
                fi
            done
        else
            echo "ERROR - 服务列表不存在，无法迁移旧系统服务，对于少部分应用存在影响" >>$logFile
        fi
    done
    echo "DEBUG - 迁移原系统中的服务完成" >>$logFile

    # baseEnv=$(echo $resourceList | awk '{print $1}')
    # serviceSrcDir="$baseEnv/usr/share/dbus-1/services"
    # serviceDstDir="/usr/share/dbus-1/services"
    # serviceDir="/opt/compatibility_layer/services"

    # ls $serviceSrcDir >$serviceDir/services-v10transfer.list
    # if [ -f $serviceDir/services-v10.list ] && [ -f $serviceDir/services-v10transfer.list ]; then
    #     diff $serviceDir/services-v10.list $serviceDir/services-v10transfer.list |
    #         awk -F "> " '/^> /{print $2}' | while read eachSrv; do
    #         echo "DEBUG - 迁移服务$eachSrv" >>$logFile
    #         if [ -f $serviceSrcDir/$eachSrv ]; then
    #             cp -p $serviceSrcDir/$eachSrv $serviceDir/$eachSrv
    #             if [ $? -ne 0 ]; then
    #                 echo "ERROR - $serviceSrcDir/$eachSrv迁移失败" >>$logFile
    #                 continue
    #             fi
    #             sed -i "s|^Exec=|Exec=$scriptName |" $serviceDir/$eachSrv >>$logFile 2>&1
    #             cp -p $serviceDir/$eachSrv $serviceDstDir/$eachSrv
    #             if [ $? -ne 0 ]; then
    #                 echo "ERROR - $serviceSrcDir/$eachSrv迁移失败" >>$logFile
    #                 continue
    #             fi
    #         else
    #             echo "ERROR - 服务文件$serviceSrcDir/$eachSrv不存在，无法迁移旧系统服务，对于少部分应用存在影响" >>$logFile
    #         fi
    #     done
    # else
    #     echo "ERROR - 服务列表不存在，无法迁移旧系统服务，对于少部分应用存在影响" >>$logFile
    # fi
    # echo "DEBUG - 迁移原系统中的服务完成" >>$logFile
}

function nonUpgradeFun() {
    echo "DEBUG - 非升级场景" >>$logFile
    # 检测系统版本 v10 v10sp1 v11
    systemVersion=$(cat /etc/os-release | grep -i PROJECT_CODENAME | awk -F= '{print $2}')
    echo "DEBUG - 宿主机系统版本是: "$systemVersion >>$logFile

    # 制作相应系统版本的 OCI image
    # 创建docker工作空间
    echo "DEBUG - 创建工作空间" >>$logFile

    resourcePre="kare-"
    resourceList=$(find / -maxdepth 1 -type d -name "$resourcePre*")
    echo $resourceList

    [ -z "$resourceList" ] && echo "DEBUG - 不存在基础环境目录,程序退出" | tee -a $logFile && exit 0

    for resourceDir in $resourceList; do
        resourcePost=${resourceDir##*-}
        docker_ws=/opt/compatibility_layer/image
        docker_ws+="$resourcePost"
        if [ -d $docker_ws ]; then
            rm -rf $docker_ws/*
        else
            mkdir -p $docker_ws
        fi
        # 创建Dockerfile文件
        echo "DEBUG - 创建Dockerfile文件" >>$logFile
        echo "FROM scratch" >$docker_ws/Dockerfile
        echo "DEBUG - Dockerfile文件路径为: $docker_ws/Dockerfile" >>$logFile

        # 补充Dockerfile文件 - 环境变量
        echo -e "ENV  DISPLAY=:0 \\ \n\t LANG=zh_CN.UTF-8 \\ \n\t GTK_IM_MODULE=fcitx \\ \n\t QT4_IM_MODULE=fcitx \\
 \t XMODIFIERS=@im=fcitx \\ \n\t CLUTTER_IM_MODULE=fcitx \\ \n\t QT_IM_MODULE=fcitx" >>$docker_ws/Dockerfile

        # 补充工作空间资源 - v10、v10 sp1在某个路径中寻找资源目录
        aidList=("/bin" "/etc" "/lib" "/lib64" "/lib32" "/opt" "/sbin" "/usr" "/var")
        # otherList=("/backup" "/cdrom" "/box" "/lost+found" "/run" "/sys" "/data" "/home" "/media" "/proc" "/tmp" "/boot" "/dev" "/mnt" "/root" "/srv" "/run")
        for eachFsOld in $resourceDir/*; do
            if [ ! -d "$eachFsOld" ]; then
                continue
            fi
            # 过滤前缀
            eachFs=${eachFsOld#*${resourceDir}}
            for eachAidList in ${aidList[@]}; do
                if [ $eachAidList == $eachFs ]; then
                    echo "COPY $eachFs $eachFs" >>$docker_ws/Dockerfile
                    # p保留权限
                    cp -rp $eachFsOld $docker_ws
                    break
                fi
            done
        done

        # 补充Dockerfile文件 - 其他信息
        echo "USER 1000" >>$docker_ws/Dockerfile
        echo 'CMD ["/bin/bash"]' >>$docker_ws/Dockerfile

        # 构建OCI镜像
        dockerIsoName="baseimage_"$resourcePost
        # systemVersion=${systemVersion,,}
        # if [ "$systemVersion" == "v10sp1" ]; then
        #     # 在sp1机器上使用，构建的应该是v10的镜像
        #     dockerIsoName="baseimage_v10"
        # elif [ "$systemVersion" == "v11" ]; then
        #     # 在v11机器上使用，构建的可能是v10sp1 v10 v11镜像三者之一
        #     echo "TODO"
        # fi
        echo "DEBUG - OCI镜像名称为: $dockerIsoName" >>$logFile
        echo "DEBUG - 开始制作 OCI 镜像" >>$logFile
        docker build -t $dockerIsoName $docker_ws >>$logFile 2>&1
        if [ $? -eq 0 ]; then
            echo "DEBUG - OCI镜像构建成功" >>$logFile
        else
            echo "ERROR - OCI镜像构建失败" >>$logFile
        fi
    done
}

function main() {
    scene="$@"
    if [ $# -eq 0 ]; then
        scene="upgrade"
    fi
    if [ $scene != "upgrade" ]; then
        configtool_kare "set" $configFile "Scene" "upgrade" "no"
        nonUpgradeFun
    else
        configtool_kare "set" $configFile "Scene" "upgrade" "yes"
        upgradeFun
    fi
}

main "$@"
