#include <iostream>
#include <fstream>
#include <cstring>
#include <string>

void getFileName(const std::string& path, std::string& fileName) {
    int pos = (int)path.size() - 1;
    for (; pos >= 0; --pos) {
        if (path[pos] == '/') {
            break;
        }
    }
    fileName = path.substr(pos+1);
}

void formatDirPath(std::string& dirPath) {
    if (!dirPath.empty() || dirPath.back() != '/') {
        dirPath += '/';
    }
}

int getFileSize(std::ifstream& fin) {
    fin.seekg(0, fin.end);
    int fileSize = fin.tellg();
    fin.seekg(0);
    return fileSize;
}

void readBinFile(const std::string& path, int& bufferSize, char*& buffer) {
    std::ifstream fin(path, std::ios::binary);
    if (!fin.is_open()) {
        std::cout << "Cannot open " << path << '\n';
        return;
    }
    bufferSize = getFileSize(fin);
    buffer = new char[bufferSize];
    fin.read(buffer, bufferSize);
    fin.close();
}

void writeBinFile(const std::string& path, int bufferSize, char* buffer) {
    std::ofstream fout(path, std::ios::binary);
    if (!fout.is_open()) {
        std::cout << "Cannot open " << path << '\n';
        return;
    }
    fout.write(buffer, bufferSize);
    fout.close();
}

int main(int argc, char** argv) {
    std::string filePath;
    std::string outDir;

    if (argc != 5) {
        std::cout << "Invalid arguments\n";
        return 0;
    } else {
        for (int i = 1; i < 5; i+=2) {
            if (strcmp(argv[i], "-s") == 0) {
                filePath = argv[i+1];
            } else if (strcmp(argv[i], "-d") == 0) {
                outDir = argv[i+1];
            }
        }
        if (filePath.empty()) {
            std::cout << "Source file not found in arguments!\n";
            return 0;
        } else if (outDir.empty()) {
            std::cout << "Destination not found in arguments!\n";
            return 0;
        }
    }


    std::string fileName;
    getFileName(filePath, fileName);

    formatDirPath(outDir);
    std::string outPath = outDir + fileName;

    int bufferSize;
    char* buffer = nullptr;
    readBinFile(filePath, bufferSize, buffer);

    writeBinFile(outPath, bufferSize, buffer);

    delete[] buffer;

    return 0;
}