/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#ifndef BUFRMETADATA_H
#define BUFRMETADATA_H

#include <iostream>
#include <map>
#include <vector>
#include <list>
#include <set>
#include <assert.h>

#ifdef METVIEW
#include <Metview.h>
#endif

#include "MvMessageMetaData.h"

#include "eccodes.h"

using namespace std;

class BufrFilterDef;
class BufrLocationCollector;
class MvKeyProfile;
class MvKey;
class MvEccBufrMessage;

class BufrDataDump
{
public:
    BufrDataDump() {}
    ~BufrDataDump();
    void clear();
    bool read(const string&, int, int, int, bool, long, std::string&);
    bool debug(const string&, int, int, int, bool, long, std::string&);
    const std::string& text() const { return text_; }
    const std::string& debug() const { return debug_; }
    const std::string& debugInfo() const { return debugInfo_; }

    bool runMessageFilter(const std::string& filterStr, const std::string& fileName,
                          const std::string& resFile);

protected:
    bool filterMessage(const std::string& inFile, int msgCnt, long offset, const std::string& outFile, std::string&);
    bool filterSubset(const std::string& inFile, int msgCnt, int subsetCnt, const std::string& outFile, std::string&);

    std::string dumpFile_;
    std::string text_;
    std::string debug_;
    std::string debugInfo_;
};

class BufrMetaData : public MvMessageMetaData
{
public:
    BufrMetaData();
    BufrMetaData(const std::string& fileName, int totalMessageNum);

    ~BufrMetaData();
    void setFileName(string);

    void getKeyList(string, MvKeyProfile*);

    void setTotalMessageNum(int);
    void setMessage(size_t chunkStart, const std::vector<MvEccBufrMessage*>& msgVec);
    std::vector<MvEccBufrMessage*> messages() const { return messages_; }
    MvEccBufrMessage* message(int) const;

    void readCompressedData(MvKeyProfile* prof, int index, int subsetNum);
    bool readLocations(BufrLocationCollector* collector, std::string& errOut);
    const std::string& firstTypicalDate() const { return firstTypicalDate_; }
    const std::set<std::string>& firstMessageKeys();
    void readMessageKeys(int index, std::set<std::string>&);

    void clearData();

protected:
    void clear();

private:
    int computeTotalMessageNum();
    void allocateMessages();

    void readCompressedData(MvKeyProfile* prof, codes_handle* ch);
    void readMessageLocations(codes_handle* ch, int msgCnt, BufrLocationCollector* collector);
    void readDoubleArray(codes_handle* ch, const std::string& key, std::size_t len, std::size_t& allocLen, double** data);

    string formatDate(string, string, string);
    string formatTime(string, string, string);

    string tmpFile_;
    MvKeyProfile* allKey_;
    std::vector<MvEccBufrMessage*> messages_;
    std::string firstTypicalDate_;
    std::set<std::string> firstKeys_;
    int broadcastStep_;
};

#endif  // BUFRMETADATA_H
