#include "pkginfo.h"
#include <iterator>
#include <unistd.h>

int pkginfo::run(int argc, char** argv)
{
   //
   // Check command line options
   //
   enum { unspecified_mode, installed_mode, list_mode, owner_mode } o_mode = unspecified_mode;
   string o_root;
   string o_arg;

   for (int i = 1; i < argc; i++) {
      string option(argv[i]);
      if (option == "-i" || option == "--installed") {
         o_mode = installed_mode;
      } else if (option == "-l" || option == "--list") {
         o_mode = list_mode;
         check_argument(argv, argc, i);
         o_arg = argv[i + 1];
         i++;
      } else if (option == "-o" || option == "--owner") {
         o_mode = owner_mode;
         check_argument(argv, argc, i);
         o_arg = argv[i + 1];
         i++;
      } else if (option == "-r" || option == "--root") {
         check_argument(argv, argc, i);
         o_root = argv[i + 1];
         i++;
      } else if (option == "-v" || option == "--version") {
         print_version();
      } else if (option == "-h" || option == "--help") {
         print_help();
      } else {
         print_invalid_option(option);
      }
   }

   if (o_mode == unspecified_mode)
      print_option_missing();

   db_open(o_root);
   if (o_mode == installed_mode) {
      for (packages_t::const_iterator i = packages.begin(); i != packages.end(); i++)
         cout << (*i).first << " " << (*i).second.version << endl;
   } else if (o_mode == list_mode) {
      if (db_find_pkg(o_arg)) {
         copy(packages[o_arg].files.begin(), packages[o_arg].files.end(), ostream_iterator<string>(cout, "\n"));         
      } else if (file_exists(o_arg)) {
         pair<string, pkginfo_t> package = pkg_open(o_arg);
         copy(package.second.files.begin(), package.second.files.end(), ostream_iterator<string>(cout, "\n"));
      } else {
         print_error() << o_arg << " is neither an installed package nor a package file" << endl;
         return EXIT_ERROR;
      }
   } else if (o_mode == owner_mode) {
      if (o_root.empty()) {
         if (o_arg[0] != '/') {
            char* cwd = getcwd(0, 0);
            o_arg = string(cwd) + "/" + o_arg;
            free(cwd);
         }
      }
      if (o_arg[0] == '/')
         o_arg.erase(0, 1);
      for (packages_t::const_iterator i = packages.begin(); i != packages.end(); i++)
         if ((*i).second.files.find(o_arg) != (*i).second.files.end())
            cout << (*i).first << " " << (*i).second.version << endl;
   } else {
      print_error() << "internal error" << endl;
      return EXIT_ERROR;
   }

   return EXIT_OK;
}

void pkginfo::print_help() const
{
   cout << "Usage: " << name() << " [OPTION]..." << endl
        << "Print different kind of information about installed" << endl
	<< "packages on the system." << endl << endl
        << "  -i, --installed             list installed packages" << endl
        << "  -l, --list <package|file>   list files in <package> or <file>" << endl
        << "  -o, --owner <file>          list owners of <file>" << endl
        << "  -r, --root <path>           use alternative root directory" << endl
        << "  -h, --help                  print this help and exit" << endl
        << "  -v, --version               output version information and exit" << endl << endl
	<< "Report bugs to <johne@rootlinux.org>." << endl;
   exit(EXIT_ERROR);
}