#include "trie.h"

extern "C" {

namespace {

class FindCallback {
 public:
  typedef int (*Func)(void *, marisa_uint32, size_t);

  FindCallback(Func func, void *first_arg)
      : func_(func), first_arg_(first_arg) {}
  FindCallback(const FindCallback &callback)
      : func_(callback.func_), first_arg_(callback.first_arg_) {}

  bool operator()(marisa::UInt32 key_id, std::size_t key_length) const {
    return func_(first_arg_, key_id, key_length) != 0;
  }

 private:
  Func func_;
  void *first_arg_;

  // Disallows assignment.
  FindCallback &operator=(const FindCallback &);
};

class PredictCallback {
 public:
  typedef int (*Func)(void *, marisa_uint32, const char *, size_t);

  PredictCallback(Func func, void *first_arg)
      : func_(func), first_arg_(first_arg) {}
  PredictCallback(const PredictCallback &callback)
      : func_(callback.func_), first_arg_(callback.first_arg_) {}

  bool operator()(marisa::UInt32 key_id, const std::string &key) const {
    return func_(first_arg_, key_id, key.c_str(), key.length()) != 0;
  }

 private:
  Func func_;
  void *first_arg_;

  // Disallows assignment.
  PredictCallback &operator=(const PredictCallback &);
};

}  // namespace

struct marisa_trie_ {
 public:
  marisa_trie_() : trie(), mapper() {}

  marisa::Trie trie;
  marisa::Mapper mapper;

 private:
  // Disallows copy and assignment.
  marisa_trie_(const marisa_trie_ &);
  marisa_trie_ &operator=(const marisa_trie_ &);
};

marisa_status marisa_init(marisa_trie **h) {
  if ((h == NULL) || (*h != NULL)) {
    return MARISA_HANDLE_ERROR;
  }
  *h = new (std::nothrow) marisa_trie_();
  return (*h != NULL) ? MARISA_OK : MARISA_MEMORY_ERROR;
}

marisa_status marisa_end(marisa_trie *h) {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  }
  delete h;
  return MARISA_OK;
}

marisa_status marisa_build(marisa_trie *h, const char * const *keys,
    size_t num_keys, const size_t *key_lengths, const double *key_weights,
    marisa_uint32 *key_ids, int flags) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  }
  h->trie.build(keys, num_keys, key_lengths, key_weights, key_ids, flags);
  h->mapper.clear();
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_mmap(marisa_trie *h, const char *filename,
    long offset, int whence) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  }
  h->trie.mmap(&h->mapper, filename, offset, whence);
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_map(marisa_trie *h, const void *ptr, size_t size) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  }
  h->trie.map(ptr, size);
  h->mapper.clear();
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_load(marisa_trie *h, const char *filename,
    long offset, int whence) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  }
  h->trie.load(filename, offset, whence);
  h->mapper.clear();
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_fread(marisa_trie *h, FILE *file) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  }
  h->trie.fread(file);
  h->mapper.clear();
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_read(marisa_trie *h, int fd) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  }
  h->trie.read(fd);
  h->mapper.clear();
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_save(const marisa_trie *h, const char *filename,
    int trunc_flag, long offset, int whence) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  }
  h->trie.save(filename, trunc_flag != 0, offset, whence);
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_fwrite(const marisa_trie *h, FILE *file) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  }
  h->trie.fwrite(file);
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_write(const marisa_trie *h, int fd) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  }
  h->trie.write(fd);
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_restore(const marisa_trie *h, marisa_uint32 key_id,
    char *key_buf, size_t key_buf_size, size_t *key_length) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  } else if (key_length == NULL) {
    return MARISA_PARAM_ERROR;
  }
  *key_length = h->trie.restore(key_id, key_buf, key_buf_size);
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_lookup(const marisa_trie *h,
    const char *ptr, size_t length, marisa_uint32 *key_id) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  } else if (key_id == NULL) {
    return MARISA_PARAM_ERROR;
  }
  if (length == MARISA_ZERO_TERMINATED) {
    *key_id = h->trie.lookup(ptr);
  } else {
    *key_id = h->trie.lookup(ptr, length);
  }
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_find(const marisa_trie *h,
    const char *ptr, size_t length,
    marisa_uint32 *key_ids, size_t *key_lengths,
    size_t max_num_results, size_t *num_results) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  } else if (num_results == NULL) {
    return MARISA_PARAM_ERROR;
  }
  if (length == MARISA_ZERO_TERMINATED) {
    *num_results = h->trie.find(ptr, key_ids, key_lengths, max_num_results);
  } else {
    *num_results = h->trie.find(ptr, length,
        key_ids, key_lengths, max_num_results);
  }
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_find_first(const marisa_trie *h,
    const char *ptr, size_t length,
    marisa_uint32 *key_id, size_t *key_length) {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  } else if (key_id == NULL) {
    return MARISA_PARAM_ERROR;
  }
  if (length == MARISA_ZERO_TERMINATED) {
    *key_id = h->trie.find_first(ptr, key_length);
  } else {
    *key_id = h->trie.find_first(ptr, length, key_length);
  }
  return MARISA_OK;
}

marisa_status marisa_find_last(const marisa_trie *h,
    const char *ptr, size_t length,
    marisa_uint32 *key_id, size_t *key_length) {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  } else if (key_id == NULL) {
    return MARISA_PARAM_ERROR;
  }
  if (length == MARISA_ZERO_TERMINATED) {
    *key_id = h->trie.find_last(ptr, key_length);
  } else {
    *key_id = h->trie.find_last(ptr, length, key_length);
  }
  return MARISA_OK;
}

marisa_status marisa_find_callback(const marisa_trie *h,
    const char *ptr, size_t length,
    int (*callback)(void *, marisa_uint32, size_t),
    void *first_arg_to_callback) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  } else if (callback == NULL) {
    return MARISA_PARAM_ERROR;
  }
  if (length == MARISA_ZERO_TERMINATED) {
    h->trie.find_callback(ptr,
        ::FindCallback(callback, first_arg_to_callback));
  } else {
    h->trie.find_callback(ptr, length,
        ::FindCallback(callback, first_arg_to_callback));
  }
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_predict(const marisa_trie *h,
    const char *ptr, size_t length, marisa_uint32 *key_ids,
    size_t max_num_results, size_t *num_results) {
  return marisa_predict_breadth_first(h, ptr, length,
      key_ids, max_num_results, num_results);
}

marisa_status marisa_predict_breadth_first(const marisa_trie *h,
    const char *ptr, size_t length, marisa_uint32 *key_ids,
    size_t max_num_results, size_t *num_results) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  } else if (num_results == NULL) {
    return MARISA_PARAM_ERROR;
  }
  if (length == MARISA_ZERO_TERMINATED) {
    *num_results = h->trie.predict_breadth_first(
        ptr, key_ids, NULL, max_num_results);
  } else {
    *num_results = h->trie.predict_breadth_first(
        ptr, length, key_ids, NULL, max_num_results);
  }
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_predict_depth_first(const marisa_trie *h,
    const char *ptr, size_t length, marisa_uint32 *key_ids,
    size_t max_num_results, size_t *num_results) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  } else if (num_results == NULL) {
    return MARISA_PARAM_ERROR;
  }
  if (length == MARISA_ZERO_TERMINATED) {
    *num_results = h->trie.predict_depth_first(
        ptr, key_ids, NULL, max_num_results);
  } else {
    *num_results = h->trie.predict_depth_first(
        ptr, length, key_ids, NULL, max_num_results);
  }
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

marisa_status marisa_predict_callback(const marisa_trie *h,
    const char *ptr, size_t length,
    int (*callback)(void *, marisa_uint32, const char *, size_t),
    void *first_arg_to_callback) try {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  } else if (callback == NULL) {
    return MARISA_PARAM_ERROR;
  }
  if (length == MARISA_ZERO_TERMINATED) {
    h->trie.predict_callback(ptr,
        ::PredictCallback(callback, first_arg_to_callback));
  } else {
    h->trie.predict_callback(ptr, length,
        ::PredictCallback(callback, first_arg_to_callback));
  }
  return MARISA_OK;
} catch (const marisa::Exception &ex) {
  return ex.status();
}

size_t marisa_get_num_tries(const marisa_trie *h) {
  return (h != NULL) ? h->trie.num_tries() : 0;
}

size_t marisa_get_num_keys(const marisa_trie *h) {
  return (h != NULL) ? h->trie.num_keys() : 0;
}

size_t marisa_get_num_nodes(const marisa_trie *h) {
  return (h != NULL) ? h->trie.num_nodes() : 0;
}

size_t marisa_get_total_size(const marisa_trie *h) {
  return (h != NULL) ? h->trie.total_size() : 0;
}

marisa_status marisa_clear(marisa_trie *h) {
  if (h == NULL) {
    return MARISA_HANDLE_ERROR;
  }
  h->trie.clear();
  h->mapper.clear();
  return MARISA_OK;
}

}  // extern "C"
