// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <lz4/lz4frame.h>

#define BLOCK_SIZE 65536

#define WR_NEWFILE O_WRONLY | O_CREAT | O_TRUNC
#define PERM_644 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH

static void usage(const char* arg0) {
    printf("usage: %s [-1|-9] [-d] <input file> <output file>\n", arg0);
    printf("   -1  fast compression (default)\n");
    printf("   -9  high compression (slower)\n");
    printf("   -d  decompress\n");
}

static int do_decompress(const char* infile, const char* outfile) {
    int infd, outfd;

    infd = open(infile, O_RDONLY);
    if (infd < 0) {
        fprintf(stderr, "could not open %s: %s\n", infile, strerror(errno));
        return -1;
    }

    outfd = open(outfile, WR_NEWFILE, PERM_644);
    if (outfd < 0) {
        fprintf(stderr, "could not open %s: %s\n", outfile, strerror(errno));
        close(infd);
        return -1;
    }

    LZ4F_decompressionContext_t dctx;
    LZ4F_errorCode_t errc = LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION);
    if (LZ4F_isError(errc)) {
        fprintf(stderr, "could not initialize decompression: %s\n", LZ4F_getErrorName(errc));
        close(outfd);
        close(infd);
        return -1;
    }

    uint8_t inbuf[BLOCK_SIZE];
    uint8_t outbuf[BLOCK_SIZE];

    // Read first 4 bytes to let LZ4 tell us how much it expects in the first
    // pass.
    size_t src_sz = 4;
    size_t dst_sz = 0;
    ssize_t nr = read(infd, inbuf, src_sz);
    if (nr < (ssize_t)src_sz) {
        fprintf(stderr, "could not read from %s", infile);
        if (nr < 0) {
            fprintf(stderr, ": %s", strerror(errno));
        }
        fprintf(stderr, "\n");
        goto done;
    }
    size_t to_read = LZ4F_decompress(dctx, outbuf, &dst_sz, inbuf, &src_sz, NULL);
    if (LZ4F_isError(to_read)) {
        fprintf(stderr, "could not decompress %s: %s\n", infile, LZ4F_getErrorName(to_read));
        goto done;
    }
    if (to_read > BLOCK_SIZE) {
        to_read = BLOCK_SIZE;
    }

    while ((nr = read(infd, inbuf, to_read)) > 0) {
        src_sz = nr;
        ssize_t pos = 0;
        size_t next = 0;

        while (pos < nr) {
            dst_sz = BLOCK_SIZE;
            next = LZ4F_decompress(dctx, outbuf, &dst_sz, inbuf + pos, &src_sz, NULL);
            if (LZ4F_isError(next)) {
                fprintf(stderr, "could not decompress %s: %s\n", infile, LZ4F_getErrorName(to_read));
                goto done;
            }

            if (dst_sz) {
                ssize_t nw = write(outfd, outbuf, dst_sz);
                if (nw != (ssize_t)dst_sz) {
                    fprintf(stderr, "could not write to %s", outfile);
                    if (nw < 0) {
                        fprintf(stderr, ": %s", strerror(errno));
                    }
                    fprintf(stderr, "\n");
                    goto done;
                }
            }
            pos += src_sz;
            src_sz = nr - pos;
        }

        to_read = next;
        if (to_read > BLOCK_SIZE || to_read == 0) {
            to_read = BLOCK_SIZE;
        }
    }

    if (nr < 0) {
        fprintf(stderr, "error reading %s: %s\n", infile, strerror(errno));
        goto done;
    }

done:
    LZ4F_freeDecompressionContext(dctx);
    close(outfd);
    close(infd);
    return 0;
}

static int do_compress(const char* infile, const char* outfile, int clevel) {
    int infd, outfd;

    infd = open(infile, O_RDONLY);
    if (infd < 0) {
        fprintf(stderr, "could not open %s: %s\n", infile, strerror(errno));
        return -1;
    }

    outfd = open(outfile, WR_NEWFILE, PERM_644);
    if (outfd < 0) {
        fprintf(stderr, "could not open %s: %s\n", outfile, strerror(errno));
        close(infd);
        return -1;
    }

    LZ4F_preferences_t prefs;
    memset(&prefs, 0, sizeof(prefs));
    prefs.compressionLevel = clevel;

    uint8_t inbuf[BLOCK_SIZE];
    size_t outsize = LZ4F_compressFrameBound(BLOCK_SIZE, &prefs);
    uint8_t* outbuf = malloc(outsize);
    if (!outbuf) {
        fprintf(stderr, "out of memory\n");
        close(outfd);
        close(infd);
        return ENOMEM;
    }

    // TODO: do the whole file in one frame, using the LZ4F begin/update/end
    // functions.
    ssize_t nr = 0;
    while ((nr = read(infd, inbuf, BLOCK_SIZE)) > 0) {
        ssize_t csz = LZ4F_compressFrame(outbuf, outsize, inbuf, nr, &prefs);
        if (LZ4F_isError(csz)) {
            fprintf(stderr, "error compressing %s: %s\n", infile, LZ4F_getErrorName(csz));
            goto done;
        }

        ssize_t nw = write(outfd, outbuf, csz);
        if (nw != csz) {
            fprintf(stderr, "could not write to %s", outfile);
            if (nw < 0) {
                fprintf(stderr, ": %s", strerror(errno));
            }
            fprintf(stderr, "\n");
            goto done;
        }
    }

    if (nr < 0) {
        fprintf(stderr, "error reading %s: %s\n", infile, strerror(errno));
        goto done;
    }

done:
    free(outbuf);
    close(outfd);
    close(infd);
    return 0;
}

int main(int argc, char* argv[]) {
    int clevel = 1;
    bool decompress = false;
    const char* infile = NULL;
    const char* outfile = NULL;

    for (int i = 1; i < argc; i++) {
        if (!strcmp("-d", argv[i])) {
            decompress = true;
            continue;
        }
        if (!strcmp("-9", argv[i])) {
            clevel = 9;
            continue;
        }
        if (!strcmp("-h", argv[i])) {
            usage(argv[0]);
            return 0;
        }

        if (!infile) {
            infile = argv[i];
            continue;
        }
        if (!outfile) {
            outfile = argv[i];
            continue;
        }

        fprintf(stderr, "Unknown argument: %s\n", argv[i]);
        usage(argv[0]);
        return -1;
    }

    if (!infile || !outfile) {
        usage(argv[0]);
        return 0;
    }

    printf("%scompressing %s into %s",
            decompress ? "de" : "",
            infile,
            outfile);
    if (!decompress) {
        printf(" at level %d", clevel);
    }
    printf("\n");

    if (decompress) {
        return do_decompress(infile, outfile);
    } else {
        return do_compress(infile, outfile, clevel);
    }
}
