/***************************** 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 *************************************/

// MvPrepBufrPrep.h

#pragma once

#include <fstream>
#include <iomanip>
#include <iostream>
#include <vector>
#include "fstream_mars_fix.h"

#include "MvBufrObs.h"

namespace metview
{

class MvObsSet;

//_____________________________________________________

class MvPrepBufrPrep  // : public MvService
{
private:
    MvPrepBufrPrep();
    MvPrepBufrPrep(const MvPrepBufrPrep& anOther);
    void operator=(const MvPrepBufrPrep& anOther);

public:
    MvPrepBufrPrep(MvObsSet& os) :
        obsSet_(os) {}
    ~MvPrepBufrPrep();

    bool prepareAll();

protected:
    bool createPrepBufrTableDir();
    bool createTablesDecodeLinks(MvObs& firstObs);
    bool setNewBufrTablesDir();
    bool extractPrepBufrTables();
    bool createDataDecodeLinks();
    void revertBufrTablesDir();

private:
    MvObsSet& obsSet_;  //-- use a reference to MvObsSet
    std::string origBufrTableDir_;
    std::string prepBufrTableDir_;
    std::string prepBufrTable_B_;
    std::string prepBufrTable_D_;
};

//_____________________________________________________

class MvTableExtract  // : public MvService
{
private:
    MvTableExtract();
    MvTableExtract(const MvTableExtract& anOther);
    void operator=(const MvTableExtract& anOther);

public:
    MvTableExtract(MvObsSet& os) :
        obsSet_(os) {}
    ~MvTableExtract() = default;

    bool extract(std::string& prepBufrTable_B, std::string& prepBufrTable_D);
    bool initTableFiles(std::string& prepBufrTable_B, std::string& prepBufrTable_D);

private:
    MvObsSet& obsSet_;  //-- use a reference to MvObsSet
    MvObs tableMsg_;
    std::ofstream table_B_;
    std::ofstream table_D_;
};
//_____________________________________________________

class TableB_entry
{
public:
    TableB_entry() = default;
    ~TableB_entry() = default;

    bool getEntry(MvObs& obs);
    void writeEntry(std::ofstream& fout);
    std::string descr() const { return descriptor_; }

private:
    std::string descriptor_;
    std::string name_;
    std::string unit_;
    std::string scale_;
    std::string refval_;
    std::string width_;
};
//_____________________________________________________

class TableD_entry
{
public:
    TableD_entry() = default;
    ~TableD_entry() = default;

    bool getEntry(MvObs& obs);
    void writeEntry(std::ofstream& fout);
    std::string descr() const { return descriptor_; }

private:
    std::string descriptor_;
    int cnt_;
    std::vector<std::string> descrlist_;
};
//_____________________________________________________

}  // namespace metview
