// ========================================================= //
//                                                           //
//   File      : LabelTranslator.h                           //
//   Purpose   : Translate tree labels                       //
//                                                           //
//   Coded by Ralf Westram (coder@reallysoft.de) in Sep 21   //
//   http://www.arb-home.de/                                 //
//                                                           //
// ========================================================= //

#ifndef LABELTRANSLATOR_H
#define LABELTRANSLATOR_H

#ifndef ARBDB_BASE_H
#include <arbdb_base.h>
#endif
#ifndef ARB_UNORDERED_MAP_H
#include <arb_unordered_map.h>
#endif
#ifndef _GLIBCXX_STRING
#include <string>
#endif
#ifndef ERRORORTYPE_H
#include <ErrorOrType.h>
#endif

typedef arb_unordered_map<std::string, std::string> StringMap;
typedef ErrorOr<std::string> ErrorOrLabel;

class TranslationReport;

class LabelTranslator {
    virtual ErrorOrLabel translate(const char *label) const = 0; // @@@ require two translate() methods: 1. for label->identifier, 2. for species->identifier

public:
    virtual ~LabelTranslator() {}

    virtual GB_ERROR generate_species_identifiers(GBDATA *gb_main) const = 0;
    GB_ERROR translate_unlinked_labels_in_tree(TreeNode *tree, TranslationReport& report) const;
};

class LabelForwarder : public LabelTranslator {
    // does not translate anything, just forwards Labels as found.

    ErrorOrLabel translate(const char *label) const OVERRIDE {
        return ErrorOrLabel(NULp, label); // performs no translation
    }

public:
    GB_ERROR generate_species_identifiers(GBDATA *) const OVERRIDE {
        return NULp;
    }
};

class ACI_LabelTranslator : public LabelTranslator {
    std::string       species_aci;          // ACI that translates each species in DB into unique identifier
    mutable StringMap identifier2shortname; // identifier is result of 'species_aci' (key=identifier, value=comma-separated list of shortname generated from)

    ErrorOrLabel translate(const char *label) const OVERRIDE;

public:
    ACI_LabelTranslator(const char *species_aci_) :
        species_aci(species_aci_)
    {}
    GB_ERROR generate_species_identifiers(GBDATA *gb_main) const OVERRIDE;
};

GB_ERROR TREE_translate_labels(GBDATA *gb_main, TreeNode *tree, const LabelTranslator& translator);

#else
#error LabelTranslator.h included twice
#endif // LABELTRANSLATOR_H


