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

#pragma once

#include "Thermo.h"

namespace metview {
class MvObs;
class MvObsSetIterator;
}

class MvNetCDF;

class BufrStation
{
    friend class BufrThermo;
public:
    BufrStation() = default;
    bool initObsIter(MvObsSetIterator&) const;

protected:
    double lat_{0};
    double lon_{0};
    double threshold_{0.1}; //in degrees
    std::string wmoName_;
    long wmoIdent_;
    int wigosSeries_{-1};
    int wigosIssuer_{-1};
    int wigosIssueNumber_{-1};
    std::string wigosLocalName_;

    enum PointMode {NoMode, CoordMode, WmoNameMode, WmoIdentMode, WigosMode};
    PointMode pointMode_{NoMode};
};

class BufrThermo : public Thermo
{
public:
    // Constructors
    BufrThermo();
    BufrThermo(const char*);

    // Destructor
    ~BufrThermo() {}

    // Allocate data values storage
    void allocateDataMemory();

    // Initialise data values storage
    void initialiseDataMemory();

    // Process data and build all data structures
    bool processData() override;

    //  Post-process and generate NetCDF output
    bool generate(MvNetCDF&, MvObs&);

    // Generate output request
    bool createOutputRequest(MvRequest&) override;

    // Create a default title
    std::string title();

protected:
    // Get application specific parameters
    bool getAppParameters(MvRequest&) override;

    // Initialise a netCDF file: variables, dimensions and attributes
    bool ncInit(MvNetCDF&, MvObs&);

    // Get Identification and Location from the Bufr data
    bool getIdent(MvRequest&, MvObsSetIterator&);
    bool getIdentName(MvRequest& station, MvObsSetIterator& iter);
    bool getLocation(MvRequest&, MvObsSetIterator&);

    // Get the maximum number of pressure levels
    void evaluateNLevels(MvObsSetIterator&, int& msgNum, int& maxLevNum);

    bool checkIdent(long ident, bool failOnError) const;
    void checkThreshold(double threshold) const;

    // Variables members
    int counter_{0};    // number of thermo data
    int pCount_{0};     // number of levels
    int nlev_{0};       // maximum number of levels
    int nTIME_STR_{13};  // 13 - yyyymmddhhmm + 1 ('end of string')

    std::vector<double> T_;  // variables data
    std::vector<double> P_;
    std::vector<double> TD_;
    std::vector<double> U_;
    std::vector<double> V_;
    std::vector<double> Z_;

    BufrStation station_;
};
