/* chmd_find: tests fast-find functionality
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mspack.h>
#include "mspack/macros.h"
#include <error.h>

void find(struct mschm_decompressor *chmd, struct mschmd_header *chm,
          char *archive, char *filename, struct mschmd_file *compare)
{
    struct mschmd_file result;
    if (chmd->fast_find(chmd, chm, filename, &result, sizeof(result))) {
        fprintf(stderr, "%s: find error on \"%s\": %s\n",
                archive, filename, ERROR(chmd));
    }
    else if (!result.section) {
        if (compare) {
            fprintf(stderr, "%s: file \"%s\" not found\n", archive, filename);
        }
        else {
            printf("%s: file \"%s\" not found\n", archive, filename);
        }
    }
    else {
        printf("%s\n", filename);
        printf(" section: %d\n", result.section->id);
        printf(" offset:  %" LD "\n", result.offset);
        printf(" length:  %" LD "\n", result.length);
        if (compare) {
            if (result.section->id != compare->section->id) {
                fprintf(stderr, "%s: found file \"%s\" section is wrong "
                        "(%d vs %d)\n", archive, filename,
                        result.section->id, compare->section->id);
            }

            if (result.offset != compare->offset) {
                fprintf(stderr, "%s: found file \"%s\" offset is wrong "
                        "(%" LD " vs %" LD ")\n", archive, filename,
                        result.offset, compare->offset);
            }

            if (result.length != compare->length) {
                fprintf(stderr, "%s: found file \"%s\" length is wrong "
                        "(%" LD " vs %" LD ")\n", archive, filename,
                        result.length, compare->length);
            }
        }
    }
}

int main(int argc, char *argv[]) {
    struct mschm_decompressor *chmd;
    struct mschmd_header *chm, *chm2;
    unsigned int i;

    if (argc < 2 || argc > 3) {
        printf("Usage: %s <file.chm> [filename to find]\n", argv[0]);
        return 1;
    }

    MSPACK_SYS_SELFTEST(i);
    if (i) return 0;

    if ((chmd = mspack_create_chm_decompressor(NULL))) {
        if ((chm = chmd->fast_open(chmd, argv[1]))) {
            if (argv[2]) {
                find(chmd, chm, argv[1], argv[2], NULL);
            }
            else {
                if ((chm2 = chmd->open(chmd, argv[1]))) {
                    struct mschmd_file *file;
                    for (file = chm2->files; file; file = file->next) {
                        find(chmd, chm, argv[1], file->filename, file);
                    }
                }
                else {
                    printf("%s: can't open -- %s\n", argv[1], ERROR(chmd));
                }
            }
            chmd->close(chmd, chm);
        }
        else {
            printf("%s: can't open -- %s\n", argv[1], ERROR(chmd));
        }
        mspack_destroy_chm_decompressor(chmd);
    }
    return 0;
}
