/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <process.h>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

struct WatchRootInfo {
    char driveLetter;
    HANDLE hThread;
    HANDLE hStopEvent;
    bool bInitialized;
    bool bUsed;
    bool bFailed;
};

struct WatchRoot {
    char *path;
    WatchRoot *next;
};

const int ROOT_COUNT = 26;

WatchRootInfo watchRootInfos[ROOT_COUNT];

WatchRoot *firstWatchRoot = NULL;

CRITICAL_SECTION csOutput;

void NormalizeSlashes(char *path, char slash) {
    for (char *p = path; *p; p++)
        if (*p == '\\' || *p == '/')
            *p = slash;
}

// -- Watchable root checks ---------------------------------------------------

bool IsNetworkDrive(const char *name) {
    const int BUF_SIZE = 1024;
    char buffer[BUF_SIZE];
    UNIVERSAL_NAME_INFO *uni = (UNIVERSAL_NAME_INFO *) buffer;
    DWORD size = BUF_SIZE;

    DWORD result = WNetGetUniversalNameA(
            name,  // path for network resource
            UNIVERSAL_NAME_INFO_LEVEL, // level of information
            buffer, // name buffer
            &size // size of buffer
    );

    return result == NO_ERROR;
}

bool IsUnwatchableFS(const char *path) {
    char volumeName[MAX_PATH];
    char fsName[MAX_PATH];
    DWORD fsFlags;
    DWORD maxComponentLength;
    SetErrorMode(SEM_FAILCRITICALERRORS);
    if (!GetVolumeInformationA(path, volumeName, MAX_PATH - 1, NULL, &maxComponentLength, &fsFlags, fsName, MAX_PATH - 1))
        return false;
    if (strcmp(fsName, "NTFS") && strcmp(fsName, "FAT") && strcmp(fsName, "FAT32") && _stricmp(fsName, "exFAT") && _stricmp(fsName, "reFS"))
        return true;

    if (!strcmp(fsName, "NTFS") && maxComponentLength != 255 && !(fsFlags & FILE_SUPPORTS_REPARSE_POINTS)) {
        // SAMBA reports itself as NTFS
        return true;
    }

    return false;
}

bool IsWatchable(const char *path) {
    if (IsNetworkDrive(path))
        return false;
    if (IsUnwatchableFS(path))
        return false;
    return true;
}

// -- Substed drive checks ----------------------------------------------------

void PrintRemapForSubstDrive(char driveLetter) {
    const int BUF_SIZE = 1024;
    char targetPath[BUF_SIZE];

    char rootPath[8];
    sprintf_s(rootPath, 8, "%c:", driveLetter);

    DWORD result = QueryDosDeviceA(rootPath, targetPath, BUF_SIZE);
    if (result == 0) {
        return;
    }
    else {
        if (targetPath[0] == '\\' && targetPath[1] == '?' && targetPath[2] == '?' && targetPath[3] == '\\') {
            // example path: \??\C:\jetbrains\idea
            NormalizeSlashes(targetPath, '/');
            printf("%c:\n%s\n", driveLetter, targetPath + 4);
        }
    }
}

void PrintRemapForSubstDrives() {
    for (int i = 0; i < ROOT_COUNT; i++) {
        if (watchRootInfos[i].bUsed) {
            PrintRemapForSubstDrive(watchRootInfos[i].driveLetter);
        }
    }
}

// -- Mount point enumeration -------------------------------------------------

const int BUFSIZE = 1024;

void PrintDirectoryReparsePoint(const char *path) {
    int size = strlen(path) + 2;
    char *directory = (char *) malloc(size);
    strcpy_s(directory, size, path);
    NormalizeSlashes(directory, '\\');
    if (directory[strlen(directory) - 1] != '\\')
        strcat_s(directory, size, "\\");

    char volumeName[_MAX_PATH];
    int rc = GetVolumeNameForVolumeMountPointA(directory, volumeName, sizeof(volumeName));
    if (rc) {
        char volumePathNames[_MAX_PATH];
        DWORD returnLength;
        rc = GetVolumePathNamesForVolumeNameA(volumeName, volumePathNames, sizeof(volumePathNames), &returnLength);
        if (rc) {
            char *p = volumePathNames;
            while (*p) {
                if (_stricmp(p, directory))   // if it's not the path we've already found
                {
                    NormalizeSlashes(directory, '/');
                    NormalizeSlashes(p, '/');
                    puts(directory);
                    puts(p);
                }
                p += strlen(p) + 1;
            }
        }
    }
    free(directory);
}

bool PrintMountPointsForVolume(HANDLE hVol, const char *volumePath, char *Buf) {
    HANDLE hPt;                  // handle for mount point scan
    char Path[BUFSIZE];          // string buffer for mount points
    DWORD dwSysFlags;            // flags that describe the file system
    char FileSysNameBuf[BUFSIZE];

    // Is this volume NTFS?
    GetVolumeInformationA(Buf, NULL, 0, NULL, NULL, &dwSysFlags, FileSysNameBuf, BUFSIZE);

    // Detect support for reparse points, and therefore for volume
    // mount points, which are implemented using reparse points.

    if (!(dwSysFlags & FILE_SUPPORTS_REPARSE_POINTS)) {
        return true;
    }

    // Start processing mount points on this volume.
    hPt = FindFirstVolumeMountPointA(
            Buf, // root path of volume to be scanned
            Path, // pointer to output string
            BUFSIZE // size of output buffer
    );

    // Shall we error out?
    if (hPt == INVALID_HANDLE_VALUE) {
        return GetLastError() != ERROR_ACCESS_DENIED;
    }

    // Process the volume mount point.
    char *buf = new char[MAX_PATH];
    do {
        strcpy_s(buf, MAX_PATH, volumePath);
        strcat_s(buf, MAX_PATH, Path);
        PrintDirectoryReparsePoint(buf);
    } while (FindNextVolumeMountPointA(hPt, Path, BUFSIZE));

    FindVolumeMountPointClose(hPt);
    return true;
}

bool PrintMountPoints(const char *path) {
    char volumeUniqueName[128];
    BOOL res = GetVolumeNameForVolumeMountPointA(path, volumeUniqueName, 128);
    if (!res) {
        return false;
    }

    char buf[BUFSIZE];            // buffer for unique volume identifiers
    HANDLE hVol;                  // handle for the volume scan

    // Open a scan for volumes.
    hVol = FindFirstVolumeA(buf, BUFSIZE);

    // Shall we error out?
    if (hVol == INVALID_HANDLE_VALUE) {
        return false;
    }

    bool success = true;
    do {
        if (!strcmp(buf, volumeUniqueName)) {
            success = PrintMountPointsForVolume(hVol, path, buf);
            if (!success) break;
        }
    } while (FindNextVolumeA(hVol, buf, BUFSIZE));

    FindVolumeClose(hVol);
    return success;
}

// -- Searching for mount points in watch roots (fallback) --------------------

void PrintDirectoryReparsePoints(const char *path) {
    char *const buf = _strdup(path);
    while (strchr(buf, '/')) {
        DWORD attributes = GetFileAttributesA(buf);
        if (attributes == INVALID_FILE_ATTRIBUTES)
            break;
        if (attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
            PrintDirectoryReparsePoint(buf);
        }
        char *pSlash = strrchr(buf, '/');
        if (pSlash) {
            *pSlash = '\0';
        }
    }
    free(buf);
}

// This is called if we got an ERROR_ACCESS_DENIED when trying to enumerate all mount points for volume.
// In this case, we walk the directory tree up from each watch root, and look at each parent directory
// to check whether it's a reparse point.
void PrintWatchRootReparsePoints() {
    WatchRoot *pWatchRoot = firstWatchRoot;
    while (pWatchRoot) {
        PrintDirectoryReparsePoints(pWatchRoot->path);
        pWatchRoot = pWatchRoot->next;
    }
}

// -- Watcher thread ----------------------------------------------------------

void PrintChangeInfo(char *rootPath, FILE_NOTIFY_INFORMATION *info) {
    char FileNameBuffer[_MAX_PATH];
    int converted = WideCharToMultiByte(CP_ACP, 0, info->FileName, info->FileNameLength / sizeof(WCHAR), FileNameBuffer, _MAX_PATH - 1, NULL, NULL);
    FileNameBuffer[converted] = '\0';
    char *command;
    if (info->Action == FILE_ACTION_ADDED || info->Action == FILE_ACTION_RENAMED_OLD_NAME) {
        command = "CREATE";
    }
    else if (info->Action == FILE_ACTION_REMOVED || info->Action == FILE_ACTION_RENAMED_OLD_NAME) {
        command = "DELETE";
    }
    else if (info->Action == FILE_ACTION_MODIFIED) {
        command = "CHANGE";
    }
    else {
        return;  // unknown command
    }

    EnterCriticalSection(&csOutput);
    puts(command);
    printf("%s", rootPath);
    puts(FileNameBuffer);
    fflush(stdout);
    LeaveCriticalSection(&csOutput);
}

void PrintEverythingChangedUnderRoot(char *rootPath) {
    EnterCriticalSection(&csOutput);
    puts("RECDIRTY");
    puts(rootPath);
    fflush(stdout);
    LeaveCriticalSection(&csOutput);
}

DWORD WINAPI WatcherThread(void *param) {
    WatchRootInfo *info = (WatchRootInfo *) param;

    OVERLAPPED overlapped;
    memset(&overlapped, 0, sizeof(overlapped));
    overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    char rootPath[8];
    sprintf_s(rootPath, 8, "%c:\\", info->driveLetter);
    HANDLE hRootDir = CreateFileA(rootPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);

    int buffer_size = 10240;
    char *buffer = new char[buffer_size];

    HANDLE handles[2];
    handles[0] = info->hStopEvent;
    handles[1] = overlapped.hEvent;
    while (true) {
        int rcDir = ReadDirectoryChangesW(hRootDir, buffer, buffer_size, TRUE,
                FILE_NOTIFY_CHANGE_FILE_NAME |
                        FILE_NOTIFY_CHANGE_DIR_NAME |
                        FILE_NOTIFY_CHANGE_ATTRIBUTES |
                        FILE_NOTIFY_CHANGE_SIZE |
                        FILE_NOTIFY_CHANGE_LAST_WRITE,
                NULL,
                &overlapped,
                NULL);
        if (rcDir == 0) {
            info->bFailed = true;
            break;
        }

        int rc = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
        if (rc == WAIT_OBJECT_0) {
            break;
        }
        if (rc == WAIT_OBJECT_0 + 1) {
            DWORD dwBytesReturned;
            if (!GetOverlappedResult(hRootDir, &overlapped, &dwBytesReturned, FALSE)) {
                info->bFailed = true;
                break;
            }

            if (dwBytesReturned == 0) {
                // don't send dirty too much, everything is changed anyway
                if (WaitForSingleObject(info->hStopEvent, 500) == WAIT_OBJECT_0)
                    break;

                // Got a buffer overflow => current changes lost => send RECDIRTY on root
                PrintEverythingChangedUnderRoot(rootPath);
            } else {
                FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION *) buffer;
                while (true) {
                    PrintChangeInfo(rootPath, info);
                    if (!info->NextEntryOffset)
                        break;
                    info = (FILE_NOTIFY_INFORMATION *)((char *) info + info->NextEntryOffset);
                }
            }
        }
    }
    CloseHandle(overlapped.hEvent);
    CloseHandle(hRootDir);
    delete[] buffer;
    return 0;
}

// -- Roots update ------------------------------------------------------------

void MarkAllRootsUnused() {
    for (int i = 0; i < ROOT_COUNT; i++) {
        watchRootInfos[i].bUsed = false;
    }
}

void StartRoot(WatchRootInfo *info) {
    info->hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    info->hThread = CreateThread(NULL, 0, &WatcherThread, info, 0, NULL);
    info->bInitialized = true;
}

void StopRoot(WatchRootInfo *info) {
    SetEvent(info->hStopEvent);
    WaitForSingleObject(info->hThread, INFINITE);
    CloseHandle(info->hThread);
    CloseHandle(info->hStopEvent);
    info->bInitialized = false;
}

void UpdateRoots() {
    char infoBuffer[256];
    strcpy_s(infoBuffer, "UNWATCHEABLE\n");
    for (int i = 0; i < ROOT_COUNT; i++) {
        if (watchRootInfos[i].bInitialized && (!watchRootInfos[i].bUsed || watchRootInfos[i].bFailed)) {
            StopRoot(&watchRootInfos[i]);
            watchRootInfos[i].bFailed = false;
        }
        if (watchRootInfos[i].bUsed) {
            char rootPath[8];
            sprintf_s(rootPath, 8, "%c:\\", watchRootInfos[i].driveLetter);
            if (!IsWatchable(rootPath)) {
                strcat_s(infoBuffer, rootPath);
                strcat_s(infoBuffer, "\n");
                continue;
            }
            if (!watchRootInfos[i].bInitialized) {
                StartRoot(&watchRootInfos[i]);
            }
        }
    }
    EnterCriticalSection(&csOutput);
    fprintf(stdout, "%s", infoBuffer);
    puts("#\nREMAP");
    PrintRemapForSubstDrives();
    bool printedMountPoints = true;
    for (int i = 0; i < ROOT_COUNT; i++) {
        if (watchRootInfos[i].bUsed) {
            char rootPath[8];
            sprintf_s(rootPath, 8, "%c:\\", watchRootInfos[i].driveLetter);
            if (!PrintMountPoints(rootPath))
                printedMountPoints = false;
        }
    }
    if (!printedMountPoints) {
        PrintWatchRootReparsePoints();
    }
    puts("#");
    fflush(stdout);
    LeaveCriticalSection(&csOutput);
}

void AddWatchRoot(const char *path) {
    WatchRoot *watchRoot = (WatchRoot *) malloc(sizeof(WatchRoot));
    watchRoot->next = NULL;
    watchRoot->path = _strdup(path);
    watchRoot->next = firstWatchRoot;
    firstWatchRoot = watchRoot;
}

void FreeWatchRootsList() {
    WatchRoot *pWatchRoot = firstWatchRoot;
    WatchRoot *pNext;
    while (pWatchRoot) {
        pNext = pWatchRoot->next;
        free(pWatchRoot->path);
        free(pWatchRoot);
        pWatchRoot = pNext;
    }
    firstWatchRoot = NULL;
}

// -- Main - filewatcher protocol ---------------------------------------------

int _tmain(int argc, _TCHAR *argv[]) {
    InitializeCriticalSection(&csOutput);

    for (int i = 0; i < 26; i++) {
        watchRootInfos[i].driveLetter = 'A' + i;
        watchRootInfos[i].bInitialized = false;
        watchRootInfos[i].bUsed = false;
    }

    char buffer[8192];
    while (true) {
        if (!gets_s(buffer, sizeof(buffer) - 1))
            break;

        if (!strcmp(buffer, "ROOTS")) {
            MarkAllRootsUnused();
            FreeWatchRootsList();
            bool failed = false;
            while (true) {
                if (!gets_s(buffer, sizeof(buffer) - 1)) {
                    failed = true;
                    break;
                }
                if (buffer[0] == '#')
                    break;
                int driveLetterPos = 0;
                char *pDriveLetter = buffer;
                if (*pDriveLetter == '|')
                    pDriveLetter++;

                AddWatchRoot(pDriveLetter);

                _strupr_s(buffer, sizeof(buffer) - 1);
                char driveLetter = *pDriveLetter;
                if (driveLetter >= 'A' && driveLetter <= 'Z') {
                    watchRootInfos[driveLetter - 'A'].bUsed = true;
                }
            }
            if (failed)
                break;

            UpdateRoots();
        }
        if (!strcmp(buffer, "EXIT"))
            break;
    }

    MarkAllRootsUnused();
    UpdateRoots();

    DeleteCriticalSection(&csOutput);
}
