/**
   * Handle status notifications
   *
   * @param StreamConsumer consumer The consumer object.
   * @param String type The status notification type.
   * @param JSONdn info The notification data.
   */
  public void onStatus(StreamConsumer consumer, String type, JSONdn info) {
    if (type.equalsIgnoreCase("info") && info.has("progress")) {
      try {
        System.err.println(info.getStringVal("progress") + "% done");
      } catch (EInvalidData e) {
        // Failed to get the progress string, ignore it
      }
    } else {
      try {
        System.err.println("STATUS: " + type + " " + info.getStringVal("message"));
      } catch (EInvalidData e1) {
        System.err.println("STATUS: " + type);
      }

      try {
        _h.reloadData();
        System.err.println(
            "STATUS: " + _h.getStatus() + " - " + String.valueOf(_h.getProgress()) + "% done");
        if (_h.getStatus().equals("succeeded")) {
          consumer.stop();
        }
      } catch (EInvalidData e) {
        System.err.println("reloadData: EInvalidData: " + e.getMessage());
      } catch (EAccessDenied e) {
        System.err.println("reloadData: EAccessDenied: " + e.getMessage());
      } catch (EAPIError e) {
        System.err.println("reloadData: EAPIError: " + e.getMessage());
      }
    }
  }
  /**
   * Factory method that takes a Historic object for websockets.
   *
   * @param user
   * @param type
   * @param definition
   * @param eventHandler
   * @return
   * @throws EAccessDenied
   * @throws ECompileFailed
   * @throws EInvalidData
   * @throws EAPIError
   */
  public static StreamConsumer historicFactory(
      User user, String type, Historic historic, IMultiStreamConsumerEvents eventHandler)
      throws EInvalidData, ECompileFailed, EAccessDenied, EAPIError {
    if (type == StreamConsumer.TYPE_WS) {
      return new WS(user, eventHandler, true, historic.getHash());
    }

    throw new EInvalidData("Unknown or inappropriate consumer type: " + type);
  }
  /**
   * Called when the connection has been established.
   *
   * @param StreamConsumer consumer The consumer object.
   */
  public void onConnect(StreamConsumer c) {
    System.err.println("Connected, starting historic query");

    // Start the historic query
    try {
      _h.start();
      System.err.println("--");
    } catch (EInvalidData e) {
      System.err.print("EInvalidData: ");
      System.err.println(e.getMessage());
    } catch (EAccessDenied e) {
      System.err.print("EAccessDenied: ");
      System.err.println(e.getMessage());
    } catch (EAPIError e) {
      System.err.print("EAPIError: ");
      System.err.println(e.getMessage());
    }
  }
  /** @param args */
  public static void main(String[] args) {
    if (args.length != 5) {
      System.err.println(
          "Usage: HistoricDump <keywords> <start_date> <end_date> <feeds> <csv_filename>");
      System.err.println("Where...");
      System.err.println("  <keywords>     comma separated list of keywords");
      System.err.println("  <start_date>   start date (yyyymmddhhmmss)");
      System.err.println("  <end_date>     end date (yyyymmddhhmmss)");
      System.err.println("  <feeds>        comma separated list of feeds (twitter,digg,etc)");
      System.err.println("  <csv_filename> filename for the csv output");
      System.exit(1);
    }

    // Config
    String csdl =
        "interaction.type == \"twitter\" and language.tag == \"en\" and interaction.content contains_any \""
            + args[0].replace("\"", "\\\"")
            + "\"";

    DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

    try {
      // Authenticate
      System.err.println("Creating user...");
      User user = new User(Config.username, Config.api_key);

      // Create the definition
      System.err.println("Creating definition...");
      Definition d = user.createDefinition(csdl);

      // Create the historic
      System.err.println("Creating historic...");
      Historic h = d.createHistoric(df.parse(args[1]), df.parse(args[2]), args[3], 100);

      // Display the playback ID
      System.err.println("Playback ID: " + h.getHash());

      // Create the consumer
      System.err.println("Getting the consumer...");
      StreamConsumer consumer =
          h.getConsumer(StreamConsumer.TYPE_HTTP, new HistoricDump(h, args[4]));

      // And start consuming
      System.err.println("Consuming...");
      System.err.println("--");
      consumer.consume();
    } catch (EInvalidData e) {
      System.err.print("InvalidData: ");
      System.err.println(e.getMessage());
    } catch (ECompileFailed e) {
      System.err.print("CompileFailed: ");
      System.err.println(e.getMessage());
    } catch (EAccessDenied e) {
      System.err.print("AccessDenied: ");
      System.err.println(e.getMessage());
    } catch (EAPIError e) {
      System.err.print("EAPIError: ");
      System.err.println(e.getMessage());
    } catch (ParseException e) {
      System.err.print("ParseException: ");
      System.err.println(e.getMessage());
    }
  }