/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the release tools of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

// constructor
function Component()
{
    // Add dynamic dependency for mingw TC for Android packages on Windows.
    if (installer.value("os") == "win") {
        var mingw_tc_component = "qt.tools.win64_mingw900"
        component.addDependency(mingw_tc_component);
    }

    // add automatic dependency to Android main node if it's selected
    dependencyStr = "qt.qt6.624.android"
    // For release builds set the dependency directly to the host binary
    var hostDependencyStr = "";
    var hostDependency = component.value("Dependencies");
    if (hostDependency) {
        if (installer.value("os") == "x11") {
            hostDependencyStr = "qt.qt6.624.gcc_64"
        }
        if (installer.value("os") == "mac") {
            hostDependencyStr = "qt.qt6.624.clang_64"
        }
        if (installer.value("os") == "win") {
            hostDependencyStr = "qt.qt6.624.win64_mingw"
        }
        component.addDependency(hostDependencyStr);
    }

    // Set automatic dependencies
    // - for release builds add dependency to the main Android node
    component.addAutoDependOn(dependencyStr);
}

Component.prototype.createOperations = function()
{
    component.createOperations();

    var qtPath = "@TargetDir@" + "/6.2.4/android_armv7";
    var cmakeBinary = "";
    var platform = "";
    var qmakeScript = "";
    var qtCMakeScript = "";
    var targetQtConf = "";
    var targetQtConf_documentation = "Documentation=../../Docs/Qt-6.2.4";
    var targetQtConf_examples = "Examples=../../Examples/Qt-6.2.4";
    var originalQmakePath = "";
    var newQmakePath = "";
    var originalSetCMakePath ="";
    var newSetCMakePath = "";
    var originalQtCMakeStandaloneTestPath = "/Users/qt/work/install/target";
    var newQtCMakeStandaloneTestPath = "";
    var originalHostPrefix = "HostPrefix=../../";
    var newHostPrefix = "";
    var originalHostData = "HostData=target";
    var newHostData = "";
    var qtToolchainCmake = "";
    var qtBuildInternalsExtraCmake = "";
    var originalQtHostPath = "/Users/qt/work/install";
    var newQtHostPath = "";
    var originalQtHostPathCmakeDir = "";
    var newQtHostPathCmakeDir = "";
    var originalQtHostTargetPath = "/Users/qt/work/install/target";
    var newQtHostTargetPath = "";

    if (installer.value("os") == "x11") {
        // CMake is installed under Tools by default for all Qt installations
        cmakeBinary = "@TargetDir@" + "/Tools/CMake/bin/cmake";
        platform = "linux";

        qmakeScript = qtPath + "/bin/qmake";
        qtCMakeScript = qtPath + "/bin/qt-cmake";
        qtCMakePrivateScript = qtPath + "/bin/qt-cmake-private";
        qtCMakeStandaloneTestScript = qtPath + "/bin/qt-cmake-standalone-test";
        targetQtConf = qtPath + "/bin/target_qt.conf";
        qtToolchainCmake = qtPath + "/lib/cmake/Qt6/qt.toolchain.cmake";
        qtBuildInternalsExtraCmake = qtPath + "/lib/cmake/Qt6BuildInternals/QtBuildInternalsExtra.cmake";
        qtPaths = qtPath + "/bin/qtpaths";

        // Initialize variables used for patching host qmake location
        // Host is qmake installed via dependencies
        originalQmakePath = "/home/qt/work/install/bin/qmake";
        newQmakePath = "@TargetDir@" + "/6.2.4/gcc_64/bin/qmake";

        // Initialize variables used for patching CMake to under Tools
        originalSetCMakePath = "/opt/cmake-3.18.3/bin/cmake";
        newSetCMakePath = cmakeBinary;

        // Initialize variable with path to bin/qt-cmake-private(.bat)
        originalQtCMakeStandaloneTestPath = "/home/qt/work/install/target";
        newQtCMakeStandaloneTestPath = qtPath;

        // Set new patched values for target_qt.confs
        newHostPrefix = "HostPrefix=../../gcc_64";
        newHostData = "HostData=../android_armv7";

        // Set new patched values for qt.toolchain.cmake
        // __qt_initial_qt_host_path
        originalQtHostPath = "/home/qt/work/install";
        newQtHostPath = "@TargetDir@" + "/6.2.4/gcc_64";
        //__qt_initial_qt_host_path_cmake_dir
        originalQtHostPathCmakeDir = "/home/qt/work/install/lib/cmake";
        newQtHostPathCmakeDir = "@TargetDir@" + "/6.2.4/gcc_64/lib/cmake";

        // Set new patched values for QtBuildInternalsExtra.cmake & qtpaths
        originalQtHostTargetPath = "/home/qt/work/install/target";
        newQtHostTargetPath = qtPath;
    }

    if (installer.value("os") == "mac") {
        var macOSTargetInstallBase = "macos";

        // CMake is installed under Tools by default for all Qt installations
        cmakeBinary = "@TargetDir@" + "/Tools/CMake/bin/cmake";
        platform = "mac";

        //qmakeScript = "@TargetDir@" + "/6.2.4/armv7/bin/qmake.bat";
        qmakeScript = qtPath + "/bin/qmake";
        qtCMakeScript = qtPath + "/bin/qt-cmake";
        qtCMakePrivateScript = qtPath + "/bin/qt-cmake-private";
        qtCMakeStandaloneTestScript = qtPath + "/bin/qt-cmake-standalone-test";
        targetQtConf = qtPath + "/bin/target_qt.conf";
        qtToolchainCmake = qtPath + "/lib/cmake/Qt6/qt.toolchain.cmake";
        qtBuildInternalsExtraCmake = qtPath + "/lib/cmake/Qt6BuildInternals/QtBuildInternalsExtra.cmake";
        qtPaths = qtPath + "/bin/qtpaths";

        // Initialize variables used for patching host qmake location
        // Host is qmake installed via dependencies
        originalQmakePath = "/Users/qt/work/install/bin/qmake";
        newQmakePath = "@TargetDir@" + "/6.2.4/" + macOSTargetInstallBase + "/bin/qmake";

        // Initialize variables used for patching CMake to under Tools
        originalSetCMakePath = "/Applications/CMake.app/Contents/bin/cmake";
        newSetCMakePath = cmakeBinary;

        // Initialize variable with path to bin/qt-cmake-private(.bat)
        newQtCMakeStandaloneTestPath = qtPath;

        // Set new patched values for target_qt.confs
        newHostPrefix = "HostPrefix=../../" + macOSTargetInstallBase;
        newHostData = "HostData=../android_armv7";

        // Set new patched values for qt.toolchain.cmake
        // __qt_initial_qt_host_path
        newQtHostPath = "@TargetDir@" + "/6.2.4/" + macOSTargetInstallBase;
        //__qt_initial_qt_host_path_cmake_dir
        originalQtHostPathCmakeDir = "/Users/qt/work/install/lib/cmake";
        newQtHostPathCmakeDir = "@TargetDir@" + "/6.2.4/" + macOSTargetInstallBase + "/lib/cmake";

        // Set new patched values for QtBuildInternalsExtra.cmake and qtpaths
        newQtHostTargetPath = qtPath;
    }

    if (installer.value("os") == "win") {
        // CMake is installed under Tools by default for all Qt installations
        cmakeBinary = "@TargetDir@" + "/Tools/CMake_64/bin/cmake.exe";
        platform = "windows";

        //qmakeScript = "@TargetDir@" + "/6.2.4/armv7/bin/qmake.bat";
        qmakeScript = qtPath + "\\bin\\qmake.bat";
        qtCMakeScript = qtPath + "\\bin\\qt-cmake.bat";
        qtCMakePrivateScript = qtPath + "\\bin\\qt-cmake-private.bat";
        qtCMakeStandaloneTestScript = qtPath + "\\bin\\qt-cmake-standalone-test.bat";
        targetQtConf = qtPath + "\\bin\\target_qt.conf";
        qtToolchainCmake = qtPath + "\\lib\\cmake\\Qt6\\qt.toolchain.cmake";
        qtBuildInternalsExtraCmake = qtPath + "\\lib\\cmake\\Qt6BuildInternals\\QtBuildInternalsExtra.cmake";
        qtPaths = qtPath + "\\bin\\qtpaths.bat";

        // Initialize variables used for patching host qmake location
        // Host is qmake installed via dependencies
        originalQmakePath = "/Users/qt/work/install/bin\\qmake.exe";
        newQmakePath = "@TargetDir@" + "\\6.2.4\\mingw_64\\bin\\qmake.exe";

        // Initialize variables used for patching CMake to under Tools
        originalSetCMakePath = "C:/CMake/bin/cmake.exe";
        newSetCMakePath = cmakeBinary.replace(/\\/g, "/");

        // Initialize variable with path to bin/qt-cmake-private(.bat)
        newQtCMakeStandaloneTestPath = qtPath;

        // Set new patched values for target_qt.conf
        newHostPrefix = "HostPrefix=../../mingw_64";
        newHostData = "HostData=../android_armv7";

        // Set new patched values for qt.toolchain.cmake
        // cmake paths can use forward slash instead of backslash in paths which is unusual for Windows
        // Make whole path using forward slash a.k.a Unix path notation instead of backslash
        var windowsTargetDir = "@TargetDir@";
        var unixTargetDir = windowsTargetDir.replace(/\\/g, "/");
        console.log("Converting path for cmake: ");
        console.log("  from windowsTargetDir: " + windowsTargetDir);
        console.log("  to unixTargetDir: " + unixTargetDir);

        // __qt_initial_qt_host_path
        newQtHostPath = unixTargetDir + "/6.2.4/mingw_64";
        //__qt_initial_qt_host_path_cmake_dir
        originalQtHostPathCmakeDir = "/Users/qt/work/install/lib/cmake";
        newQtHostPathCmakeDir = unixTargetDir + "/6.2.4/mingw_64/lib/cmake";

        // Set new patched values for QtBuildInternalsExtra.cmake and qtpaths.bat
        newQtHostTargetPath = qtPath;
    }

    // Patch build time paths from target\bin\qmake(.bat) script
    console.log("Patching qmake script: " + qmakeScript);
    console.log("  from originalQmakePath: " + originalQmakePath);
    console.log("  to newQmakePath: " + newQmakePath);
    component.addOperation("Replace", qmakeScript, originalQmakePath, newQmakePath);

    // Patch build time CMake path from qt-cmake(.bat) script
    console.log("Patching CMake path from qt-cmake script: " + qtCMakeScript);
    console.log("  from originalSetCMakePath: " + originalSetCMakePath);
    console.log("  to newSetCMakePath: " + newSetCMakePath);
    component.addOperation("Replace", qtCMakeScript, originalSetCMakePath, newSetCMakePath);

    // Patch build time CMAke paths from qt-cmake-private(.bat) script
    console.log("Patching CMake path from qt-cmake-private script: " + qtCMakePrivateScript);
    console.log("  from originalSetCMakePath: " + originalSetCMakePath);
    console.log("  to newSetCMakePath: " + newSetCMakePath);
    component.addOperation("Replace", qtCMakePrivateScript, originalSetCMakePath, newSetCMakePath);

    // Patch build time CMAke paths from qt-cmake-standalone-test(.bat) script
    console.log("Patching path from qt-cmake-standalone-test script: " + qtCMakeStandaloneTestScript);
    console.log("  from originalQtCMakeStandaloneTestPath: " + originalQtCMakeStandaloneTestPath);
    console.log("  to newQtCMakeStandaloneTestPath: " + newQtCMakeStandaloneTestPath);
    component.addOperation("Replace", qtCMakeStandaloneTestScript, originalQtCMakeStandaloneTestPath, newQtCMakeStandaloneTestPath);

    // Patch Host Prefix and Host Data paths from target_qt.conf
    console.log("Patching Host Prefix and Host Data from target_qt.conf: " + targetQtConf);
    console.log("  from originalHostPrefix: " + originalHostPrefix);
    console.log("  to newHostPrefix: " + newHostPrefix);
    console.log("  from originalHostData: " + originalHostData);
    console.log("  to newHostData: " + newHostData);
    component.addOperation("Replace", targetQtConf, originalHostPrefix, newHostPrefix);
    component.addOperation("Replace", targetQtConf , originalHostData, newHostData);

    // Append target_qt.conf with relative paths to documentation and examples
    console.log("Appending " + targetQtConf_documentation + " and " + targetQtConf_examples + " to targetQtConf" + targetQtConf);
    component.addOperation("AppendFile", targetQtConf, targetQtConf_documentation);
    // Add a new line to targetQtConf which AppendFile operation doesn't add automatically
    if (installer.value("os") == "win") {
        // \r\n = CR + LF used as a new line character in Windows
        component.addOperation("AppendFile", targetQtConf, "\r\n");
    }
    else {
        // \n = LF (Line Feed) used as a new line character in Unix/macOS
        component.addOperation("AppendFile", targetQtConf, "\n");
    }
    component.addOperation("AppendFile", targetQtConf, targetQtConf_examples);

    // Patch Qt install path from qt.toolchain.cmake
    console.log("Patching install path from qt.toolchain.cmake : " + qtToolchainCmake);
    console.log("set __qt_initial_qt_host_path");
    console.log("  from originalQtHostPath: " + originalQtHostPath);
    console.log("  to newQtHostPath: " + newQtHostPath);
    component.addOperation("Replace", qtToolchainCmake, originalQtHostPath, newQtHostPath);
    console.log("set __qt_initial_qt_host_path_cmake_dir");
    console.log("  from originalQtHostPathCmakeDir: " + originalQtHostPathCmakeDir);
    console.log("  to newQtHostPathCmakeDir: " + newQtHostPathCmakeDir);
    component.addOperation("Replace", qtToolchainCmake, originalQtHostPathCmakeDir, newQtHostPathCmakeDir);

    // Patch Qt install path from QtBuildInternalsExtra.cmake
    console.log("Patching install path from QtBuildInternalsExtra.cmake : " + qtBuildInternalsExtraCmake);
    console.log("  from originalQtHostTargetPath: " + originalQtHostTargetPath);
    console.log("  to newQtHostTargetPath: " + newQtHostTargetPath);
    component.addOperation("Replace", qtBuildInternalsExtraCmake, originalQtHostTargetPath, newQtHostTargetPath);

    // Patch Qt install path from qtpaths(.bat)
    console.log("Patching install path from qtpaths(.bat) : " + qtPaths);
    console.log("  from originalQtHostTargetPath: " + originalQtHostTargetPath);
    console.log("  to newQtHostTargetPath: " + newQtHostTargetPath);
    component.addOperation("Replace", qtPaths, originalQtHostTargetPath, newQtHostTargetPath);

    addInitQtPatchOperation(component, platform, qtPath, qmakeScript, "emb-arm-qt5");

    if (installer.value("SDKToolBinary") == "")
        return;

    // add Qt into QtCreator
    component.addOperation("Execute",
                           ["@SDKToolBinary@", "addQt",
                            "--id", component.name,
                            "--name", "Qt %{Qt:Version} for Android ARMv7",
                            "--type", "Qt4ProjectManager.QtVersion.Android",
                            "--qmake", qmakeScript,
                            "UNDOEXECUTE",
                            "@SDKToolBinary@", "rmQt", "--id", component.name]);

    // create qt.conf file
    createQtConfFiles(component, installer.value("TargetDir") + "/6.2.4/android_armv7", "Qt-6.2.4");

    // is this OpenSource installation?
    var isOpenSource = "true";
    if (['true', 'yes', '1'].indexOf(isOpenSource) >= 0) {
        // patch qconfig.pri
        var qconfigFile = qtPath + "/mkspecs/qconfig.pri";
        component.addOperation("LineReplace", qconfigFile, "QT_EDITION =", "QT_EDITION = OpenSource");
        if (installer.value("os") == "x11") {
            component.addOperation("LineReplace", qconfigFile, "QT_LICHECK = licheck64", "QT_LICHECK =");
        }
        if (installer.value("os") == "mac") {
            component.addOperation("LineReplace", qconfigFile, "QT_LICHECK = licheck_mac", "QT_LICHECK =");
        }
        if (installer.value("os") == "win") {
            component.addOperation("LineReplace", qconfigFile, "QT_LICHECK = licheck.exe", "QT_LICHECK =");
        }
    }
}

