// Copyright (c) 2011 The Chromium OS 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 <getopt.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "bmpblk_font.h"
#include "image_types.h"

static char *progname;

static void error(const char *fmt, ...)
{
    va_list args;
    va_start( args, fmt );
    fprintf(stderr, "%s: ", progname);
    vfprintf( stderr, fmt, args );
    va_end( args );
}
#define fatal(args...) do { error(args); exit(1); } while(0)


/* Command line options */
enum {
  OPT_OUTFILE = 1000,
};

#define DEFAULT_OUTFILE "font.bin"


static struct option long_opts[] = {
  {"outfile", 1, 0,                   OPT_OUTFILE             },
  {NULL, 0, 0, 0}
};


/* Print help and return error */
static void HelpAndDie(void) {
  fprintf(stderr,
          "\n"
          "%s - Create a vboot fontfile from a set of BMP files.\n"
          "\n"
          "Usage:  %s [OPTIONS] BMPFILE [BMPFILE...]\n"
          "\n"
          "Each BMP file must match *_HEX.bmp, where HEX is the hexadecimal\n"
          "representation of the character that the file displays. The images\n"
          "will be encoded in the given order. Typically the first image is\n"
          "reused to represent any missing characters.\n"
          "\n"
          "OPTIONS are:\n"
          "  --outfile <filename>      Output file (default is %s)\n"
          "\n", progname, progname, DEFAULT_OUTFILE);
  exit(1);
}

//////////////////////////////////////////////////////////////////////////////

// Returns pointer to buffer containing entire file, sets length.
static void *read_entire_file(const char *filename, size_t *length) {
  int fd;
  struct stat sbuf;
  void *ptr;

  *length = 0;                          // just in case

  if (0 != stat(filename, &sbuf)) {
    error("Unable to stat %s: %s\n", filename, strerror(errno));
    return 0;
  }

  if (!sbuf.st_size) {
    error("File %s is empty\n", filename);
    return 0;
  }

  fd = open(filename, O_RDONLY);
  if (fd < 0) {
    error("Unable to open %s: %s\n", filename, strerror(errno));
    return 0;
  }

  ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  if (MAP_FAILED == ptr) {
    error("Unable to mmap %s: %s\n", filename, strerror(errno));
    close(fd);
    return 0;
  }

  *length = sbuf.st_size;

  close(fd);

  return ptr;
}


// Reclaims buffer from read_entire_file().
static void discard_file(void *ptr, size_t length) {
  munmap(ptr, length);
}

//////////////////////////////////////////////////////////////////////////////



int main(int argc, char* argv[]) {
  char* outfile = DEFAULT_OUTFILE;
  int numimages = 0;
  int parse_error = 0;
  int i;
  FILE *ofp;
  FontArrayHeader header;
  FontArrayEntryHeader entry;

  progname = strrchr(argv[0], '/');
  if (progname)
    progname++;
  else
    progname = argv[0];

  while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
    switch (i) {
      case OPT_OUTFILE:
        outfile = optarg;
        break;

    default:
        /* Unhandled option */
        printf("Unknown option\n");
        parse_error = 1;
        break;
    }
  }

  numimages = argc - optind;

  if (parse_error || numimages < 1)
    HelpAndDie();

  printf("outfile is %s\n", outfile);
  printf("numimages is %d\n", numimages);

  ofp = fopen(outfile, "wb");
  if (!ofp)
    fatal("Unable to open %s: %s\n", outfile, strerror(errno));

  memcpy(&header.signature, FONT_SIGNATURE, FONT_SIGNATURE_SIZE);
  header.num_entries = numimages;
  if (1 != fwrite(&header, sizeof(header), 1, ofp)) {
    error("Can't write header to %s: %s\n", outfile, strerror(errno));
    goto bad1;
  }

  for(i=0; i<numimages; i++) {
    char *imgfile = argv[optind+i];
    char *s;
    uint32_t ascii;
    void *imgdata = 0;
    size_t imgsize, filesize, diff;

    s = strrchr(imgfile, '_');
    if (!s || 1 != sscanf(s, "_%x.bmp", &ascii)) { // This is not foolproof.
      error("Unable to parse the character from filename %s\n", imgfile);
      goto bad1;
    }

    imgdata = read_entire_file(imgfile, &imgsize);
    if (!imgdata)
      goto bad1;

    if (FORMAT_BMP != identify_image_type(imgdata, imgsize, &entry.info)) {
      error("%s does not contain a valid BMP image\n", imgfile);
      goto bad1;
    }

    // Pad the image to align it on a 4-byte boundary.
    filesize = imgsize;
    if (imgsize % 4)
      filesize = ((imgsize + 4) / 4) * 4;
    diff = filesize - imgsize;

    entry.ascii = ascii;
    entry.info.tag = TAG_NONE;
    entry.info.compression = COMPRESS_NONE; // we'll compress it all later
    entry.info.original_size = filesize;
    entry.info.compressed_size = filesize;

    printf("%s => 0x%x %dx%d\n", imgfile, entry.ascii,
           entry.info.width, entry.info.height);

    if (1 != fwrite(&entry, sizeof(entry), 1, ofp)) {
      error("Can't write entry to %s: %s\n", outfile, strerror(errno));
      goto bad1;
    }
    if (1 != fwrite(imgdata, imgsize, 1, ofp)) {
      error("Can't write image to %s: %s\n", outfile, strerror(errno));
      goto bad1;
    }
    if (diff && 1 != fwrite("\0\0\0\0\0\0\0\0", diff, 1, ofp)) {
      error("Can't write padding to %s: %s\n", outfile, strerror(errno));
      goto bad1;
    }


    discard_file(imgdata, imgsize);
  }

  fclose(ofp);
  return 0;

bad1:
  fclose(ofp);
  error("Aborting\n");
  (void) unlink(outfile);
  exit(1);
}
