/***************************** 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,std::string&);
    bool debug(const string&, int,int,int,bool,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,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();
    void setFileName(string);
    
    void loadKeyProfile(MvKeyProfile *);
    void getKeyList(string,MvKeyProfile*);
    int getEstimatedMessageNum();
    bool useMessageSizeForProgressIndicator();
    
    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();

protected:
    void clear();

private:
    int computeTotalMessageNum();
    void readMessages(MvKeyProfile *);
    void readMessage(MvKeyProfile* prof,codes_handle *ch,int msgCnt);
    void readMessageFailed(MvKeyProfile* prof,int msgCnt);
    void readCompressedData(MvKeyProfile* prof,codes_handle *ch);
    void readFirstMessageKeys();

    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_;
};

#endif // BUFRMETADATA_H
