/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the qmake application 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$
**
****************************************************************************/

#include "project.h"
#include "property.h"
#include "option.h"
#include "cachekeys.h"
#include "metamakefile.h"
#include <qnamespace.h>
#include <qdebug.h>
#include <qregexp.h>
#include <qdir.h>
#include <qdiriterator.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#if defined(Q_OS_UNIX)
#include <errno.h>
#include <unistd.h>
#endif

#ifdef Q_OS_WIN
#  include <qt_windows.h>
#endif

using namespace QMakeInternal;

QT_BEGIN_NAMESPACE

#ifdef Q_OS_WIN

struct SedSubst {
    QRegExp from;
    QString to;
};
Q_DECLARE_TYPEINFO(SedSubst, Q_MOVABLE_TYPE);

static int doSed(int argc, char **argv)
{
    QVector<SedSubst> substs;
    QList<const char *> inFiles;
    for (int i = 0; i < argc; i++) {
        if (!strcmp(argv[i], "-e")) {
            if (++i == argc) {
                fprintf(stderr, "Error: sed option -e requires an argument\n");
                return 3;
            }
            QString cmd = QString::fromLocal8Bit(argv[i]);
            for (int j = 0; j < cmd.length(); j++) {
                QChar c = cmd.at(j);
                if (c.isSpace())
                    continue;
                if (c != QLatin1Char('s')) {
                    fprintf(stderr, "Error: unrecognized sed command '%c'\n", c.toLatin1());
                    return 3;
                }
                QChar sep = ++j < cmd.length() ? cmd.at(j) : QChar();
                Qt::CaseSensitivity matchcase = Qt::CaseSensitive;
                bool escaped = false;
                int phase = 1;
                QStringList phases;
                QString curr;
                while (++j < cmd.length()) {
                    c = cmd.at(j);
                    if (!escaped) {
                        if (c == QLatin1Char(';'))
                            break;
                        if (c == QLatin1Char('\\')) {
                            escaped = true;
                            continue;
                        }
                        if (c == sep) {
                            phase++;
                            phases << curr;
                            curr.clear();
                            continue;
                        }
                    }
                    if (phase == 1
                        && (c == QLatin1Char('+') || c == QLatin1Char('?') || c == QLatin1Char('|')
                            || c == QLatin1Char('{') || c == QLatin1Char('}')
                            || c == QLatin1Char('(') || c == QLatin1Char(')'))) {
                        // translate sed rx to QRegExp
                        escaped ^= 1;
                    }
                    if (escaped) {
                        escaped = false;
                        curr += QLatin1Char('\\');
                    }
                    curr += c;
                }
                if (escaped) {
                    fprintf(stderr, "Error: unterminated escape sequence in sed s command\n");
                    return 3;
                }
                if (phase != 3) {
                    fprintf(stderr, "Error: sed s command requires three arguments (%d, %c, %s)\n", phase, sep.toLatin1(), qPrintable(curr));
                    return 3;
                }
                if (curr.contains(QLatin1Char('i'))) {
                    curr.remove(QLatin1Char('i'));
                    matchcase = Qt::CaseInsensitive;
                }
                if (curr != QLatin1String("g")) {
                    fprintf(stderr, "Error: sed s command supports only g & i options; g is required\n");
                    return 3;
                }
                SedSubst subst;
                subst.from = QRegExp(phases.at(0), matchcase);
                subst.to = phases.at(1);
                subst.to.replace(QLatin1String("\\\\"), QLatin1String("\\")); // QString::replace(rx, sub) groks \1, but not \\.
                substs << subst;
            }
        } else if (argv[i][0] == '-' && argv[i][1] != 0) {
            fprintf(stderr, "Error: unrecognized sed option '%s'\n", argv[i]);
            return 3;
        } else {
            inFiles << argv[i];
        }
    }
    if (inFiles.isEmpty())
        inFiles << "-";
    for (const char *inFile : qAsConst(inFiles)) {
        FILE *f;
        if (!strcmp(inFile, "-")) {
            f = stdin;
        } else if (!(f = fopen(inFile, "rb"))) {
            perror(inFile);
            return 1;
        }
        QTextStream is(f);
        while (!is.atEnd()) {
            QString line = is.readLine();
            for (int i = 0; i < substs.size(); i++)
                line.replace(substs.at(i).from, substs.at(i).to);
            puts(qPrintable(line));
        }
        if (f != stdin)
            fclose(f);
    }
    return 0;
}

static int doLink(int argc, char **argv)
{
    bool isSymlink = false;
    bool force = false;
    QList<const char *> inFiles;
    for (int i = 0; i < argc; i++) {
        if (!strcmp(argv[i], "-s")) {
            isSymlink = true;
        } else if (!strcmp(argv[i], "-f")) {
            force = true;
        } else if (argv[i][0] == '-') {
            fprintf(stderr, "Error: unrecognized ln option '%s'\n", argv[i]);
            return 3;
        } else {
            inFiles << argv[i];
        }
    }
    if (inFiles.size() != 2) {
        fprintf(stderr, "Error: this ln requires exactly two file arguments\n");
        return 3;
    }
    if (!isSymlink) {
        fprintf(stderr, "Error: this ln supports faking symlinks only\n");
        return 3;
    }
    QString target = QString::fromLocal8Bit(inFiles[0]);
    QString linkname = QString::fromLocal8Bit(inFiles[1]);

    QDir destdir;
    QFileInfo tfi(target);
    QFileInfo lfi(linkname);
    if (lfi.isDir()) {
        destdir.setPath(linkname);
        lfi.setFile(destdir, tfi.fileName());
    } else {
        destdir.setPath(lfi.path());
    }
    if (!destdir.exists()) {
        fprintf(stderr, "Error: destination directory %s does not exist\n", qPrintable(destdir.path()));
        return 1;
    }
    tfi.setFile(destdir.absoluteFilePath(tfi.filePath()));
    if (!tfi.exists()) {
        fprintf(stderr, "Error: this ln does not support symlinking non-existing targets\n");
        return 3;
    }
    if (tfi.isDir()) {
        fprintf(stderr, "Error: this ln does not support symlinking directories\n");
        return 3;
    }
    if (lfi.exists()) {
        if (!force) {
            fprintf(stderr, "Error: %s exists\n", qPrintable(lfi.filePath()));
            return 1;
        }
        if (!QFile::remove(lfi.filePath())) {
            fprintf(stderr, "Error: cannot overwrite %s\n", qPrintable(lfi.filePath()));
            return 1;
        }
    }
    if (!QFile::copy(tfi.filePath(), lfi.filePath())) {
        fprintf(stderr, "Error: cannot copy %s to %s\n",
                qPrintable(tfi.filePath()), qPrintable(lfi.filePath()));
        return 1;
    }

    return 0;
}

#endif

static bool setFilePermissions(QFile &file, QFileDevice::Permissions permissions)
{
    if (file.setPermissions(permissions))
        return true;
    fprintf(stderr, "Error setting permissions on %s: %s\n",
            qPrintable(file.fileName()), qPrintable(file.errorString()));
    return false;
}

static bool copyFileTimes(QFile &targetFile, const QString &sourceFilePath,
                          bool mustEnsureWritability, QString *errorString)
{
#ifdef Q_OS_WIN
    bool mustRestorePermissions = false;
    QFileDevice::Permissions targetPermissions;
    if (mustEnsureWritability) {
        targetPermissions = targetFile.permissions();
        if (!targetPermissions.testFlag(QFileDevice::WriteUser)) {
            mustRestorePermissions = true;
            if (!setFilePermissions(targetFile, targetPermissions | QFileDevice::WriteUser))
                return false;
        }
    }
#endif
    if (!IoUtils::touchFile(targetFile.fileName(), sourceFilePath, errorString))
        return false;
#ifdef Q_OS_WIN
    if (mustRestorePermissions && !setFilePermissions(targetFile, targetPermissions))
        return false;
#endif
    return true;
}

static int installFile(const QString &source, const QString &target, bool exe = false,
                       bool preservePermissions = false)
{
    QFile sourceFile(source);
    QFile targetFile(target);
    if (targetFile.exists()) {
#ifdef Q_OS_WIN
        targetFile.setPermissions(targetFile.permissions() | QFile::WriteUser);
#endif
        QFile::remove(target);
    } else {
        QDir::root().mkpath(QFileInfo(target).absolutePath());
    }

    if (!sourceFile.copy(target)) {
        fprintf(stderr, "Error copying %s to %s: %s\n", source.toLatin1().constData(), qPrintable(target), qPrintable(sourceFile.errorString()));
        return 3;
    }

    QFileDevice::Permissions targetPermissions = preservePermissions
            ? sourceFile.permissions()
            : (QFileDevice::ReadOwner | QFileDevice::WriteOwner
               | QFileDevice::ReadUser | QFileDevice::WriteUser
               | QFileDevice::ReadGroup | QFileDevice::ReadOther);
    if (exe) {
        targetPermissions |= QFileDevice::ExeOwner | QFileDevice::ExeUser |
                QFileDevice::ExeGroup | QFileDevice::ExeOther;
    }
    if (!setFilePermissions(targetFile, targetPermissions))
        return 3;

    QString error;
    if (!copyFileTimes(targetFile, sourceFile.fileName(), preservePermissions, &error)) {
        fprintf(stderr, "%s", qPrintable(error));
        return 3;
    }

    return 0;
}

static int installFileOrDirectory(const QString &source, const QString &target,
                                  bool preservePermissions = false)
{
    QFileInfo fi(source);
    if (false) {
#if defined(Q_OS_UNIX)
    } else if (fi.isSymLink()) {
        QString linkTarget;
        if (!IoUtils::readLinkTarget(fi.absoluteFilePath(), &linkTarget)) {
            fprintf(stderr, "Could not read link %s: %s\n", qPrintable(fi.absoluteFilePath()), strerror(errno));
            return 3;
        }
        QFile::remove(target);
        if (::symlink(linkTarget.toLocal8Bit().constData(), target.toLocal8Bit().constData()) < 0) {
            fprintf(stderr, "Could not create link: %s\n", strerror(errno));
            return 3;
        }
#endif
    } else if (fi.isDir()) {
        QDir::current().mkpath(target);

        QDirIterator it(source, QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden);
        while (it.hasNext()) {
            it.next();
            const QFileInfo &entry = it.fileInfo();
            const QString &entryTarget = target + QDir::separator() + entry.fileName();

            const int recursionResult = installFileOrDirectory(entry.filePath(), entryTarget, true);
            if (recursionResult != 0)
                return recursionResult;
        }
    } else {
        const int fileCopyResult = installFile(source, target, /*exe*/ false, preservePermissions);
        if (fileCopyResult != 0)
            return fileCopyResult;
    }
    return 0;
}

static int doQInstall(int argc, char **argv)
{
    bool installExecutable = false;
    if (argc == 3 && !strcmp(argv[0], "-exe")) {
        installExecutable = true;
        --argc;
        ++argv;
    }

    if (argc != 2 && !installExecutable) {
        fprintf(stderr, "Error: usage: [-exe] source target\n");
        return 3;
    }

    const QString source = QString::fromLocal8Bit(argv[0]);
    const QString target = QString::fromLocal8Bit(argv[1]);

    if (installExecutable)
        return installFile(source, target, /*exe=*/true);
    return installFileOrDirectory(source, target);
}


static int doInstall(int argc, char **argv)
{
    if (!argc) {
        fprintf(stderr, "Error: -install requires further arguments\n");
        return 3;
    }
#ifdef Q_OS_WIN
    if (!strcmp(argv[0], "sed"))
        return doSed(argc - 1, argv + 1);
    if (!strcmp(argv[0], "ln"))
        return doLink(argc - 1, argv + 1);
#endif
    if (!strcmp(argv[0], "qinstall"))
        return doQInstall(argc - 1, argv + 1);
    fprintf(stderr, "Error: unrecognized -install subcommand '%s'\n", argv[0]);
    return 3;
}


#ifdef Q_OS_WIN

static int dumpMacros(const wchar_t *cmdline)
{
    // from http://stackoverflow.com/questions/3665537/how-to-find-out-cl-exes-built-in-macros
    int argc;
    wchar_t **argv = CommandLineToArgvW(cmdline, &argc);
    if (!argv)
        return 2;
    for (int i = 0; i < argc; ++i) {
        if (argv[i][0] != L'-' || argv[i][1] != 'D')
            continue;

        wchar_t *value = wcschr(argv[i], L'=');
        if (value) {
            *value = 0;
            ++value;
        } else {
            // point to the NUL at the end, so we don't print anything
            value = argv[i] + wcslen(argv[i]);
        }
        wprintf(L"#define %Ls %Ls\n", argv[i] + 2, value);
    }
    return 0;
}

#endif // Q_OS_WIN

/* This is to work around lame implementation on Darwin. It has been noted that the getpwd(3) function
   is much too slow, and called much too often inside of Qt (every fileFixify). With this we use a locally
   cached copy because I can control all the times it is set (because Qt never sets the pwd under me).
*/
static QString pwd;
QString qmake_getpwd()
{
    if(pwd.isNull())
        pwd = QDir::currentPath();
    return pwd;
}
bool qmake_setpwd(const QString &p)
{
    if(QDir::setCurrent(p)) {
        pwd = QDir::currentPath();
        return true;
    }
    return false;
}

int runQMake(int argc, char **argv)
{
    // stderr is unbuffered by default, but stdout buffering depends on whether
    // there is a terminal attached. Buffering can make output from stderr and stdout
    // appear out of sync, so force stdout to be unbuffered as well.
    // This is particularly important for things like QtCreator and scripted builds.
    setvbuf(stdout, (char *)NULL, _IONBF, 0);

    // Workaround for inferior/missing command line tools on Windows: make our own!
    if (argc >= 2 && !strcmp(argv[1], "-install"))
        return doInstall(argc - 2, argv + 2);

#ifdef Q_OS_WIN
    {
        // Support running as Visual C++'s compiler
        const wchar_t *cmdline = _wgetenv(L"MSC_CMD_FLAGS");
        if (!cmdline || !*cmdline)
            cmdline = _wgetenv(L"MSC_IDE_FLAGS");
        if (cmdline && *cmdline)
            return dumpMacros(cmdline);
    }
#endif

    QMakeVfs vfs;
    Option::vfs = &vfs;
    QMakeGlobals globals;
    Option::globals = &globals;

    // parse command line
    int ret = Option::init(argc, argv);
    if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
        if ((ret & Option::QMAKE_CMDLINE_ERROR) != 0)
            return 1;
        return 0;
    }

    QString oldpwd = qmake_getpwd();

    Option::output_dir = oldpwd; //for now this is the output dir
    if (!Option::output.fileName().isEmpty() && Option::output.fileName() != "-") {
        // The output 'filename', as given by the -o option, might include one
        // or more directories, so we may need to rebase the output directory.
        QFileInfo fi(Option::output);

        QDir dir(QDir::cleanPath(fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath()));

        // Don't treat Xcode project directory as part of OUT_PWD
        if (dir.dirName().endsWith(QLatin1String(".xcodeproj"))) {
            // Note: we're intentionally not using cdUp(), as the dir may not exist
            dir.setPath(QDir::cleanPath(dir.filePath("..")));
        }

        Option::output_dir = dir.path();
        QString absoluteFilePath = QDir::cleanPath(fi.absoluteFilePath());
        Option::output.setFileName(absoluteFilePath.mid(Option::output_dir.length() + 1));
    }

    QMakeProperty prop;
    if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY ||
       Option::qmake_mode == Option::QMAKE_SET_PROPERTY ||
       Option::qmake_mode == Option::QMAKE_UNSET_PROPERTY)
        return prop.exec() ? 0 : 101;
    globals.setQMakeProperty(&prop);

    ProFileCache proFileCache;
    Option::proFileCache = &proFileCache;
    QMakeParser parser(&proFileCache, &vfs, &Option::evalHandler);
    Option::parser = &parser;

    QMakeProject project;
    int exit_val = 0;
    QStringList files;
    if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
        files << "(*hack*)"; //we don't even use files, but we do the for() body once
    else
        files = Option::mkfile::project_files;
    for(QStringList::Iterator pfile = files.begin(); pfile != files.end(); pfile++) {
        if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
           Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
            QString fn = Option::normalizePath(*pfile);
            if(!QFile::exists(fn)) {
                fprintf(stderr, "Cannot find file: %s.\n",
                        QDir::toNativeSeparators(fn).toLatin1().constData());
                exit_val = 2;
                continue;
            }

            //setup pwd properly
            debug_msg(1, "Resetting dir to: %s",
                      QDir::toNativeSeparators(oldpwd).toLatin1().constData());
            qmake_setpwd(oldpwd); //reset the old pwd
            int di = fn.lastIndexOf(QLatin1Char('/'));
            if(di != -1) {
                debug_msg(1, "Changing dir to: %s",
                          QDir::toNativeSeparators(fn.left(di)).toLatin1().constData());
                if(!qmake_setpwd(fn.left(di)))
                    fprintf(stderr, "Cannot find directory: %s\n",
                            QDir::toNativeSeparators(fn.left(di)).toLatin1().constData());
                fn = fn.right(fn.length() - di - 1);
            }

            Option::prepareProject(fn);

            // read project..
            if(!project.read(fn)) {
                fprintf(stderr, "Error processing project file: %s\n",
                        QDir::toNativeSeparators(*pfile).toLatin1().constData());
                exit_val = 3;
                continue;
            }
            if (Option::mkfile::do_preprocess) {
                project.dump();
                continue; //no need to create makefile
            }
        }

        bool success = true;
        MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false, &success);
        if (!success)
            exit_val = 3;

        if (mkfile && !mkfile->write()) {
            if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
                fprintf(stderr, "Unable to generate project file.\n");
            else
                fprintf(stderr, "Unable to generate makefile for: %s\n",
                        QDir::toNativeSeparators(*pfile).toLatin1().constData());
            exit_val = 5;
        }
        delete mkfile;
        mkfile = nullptr;
    }
    qmakeClearCaches();
    return exit_val;
}

QT_END_NAMESPACE

int main(int argc, char **argv)
{
    return QT_PREPEND_NAMESPACE(runQMake)(argc, argv);
}
