#ifndef _JFX_INTERFACE_DEFINE_H_
#define _JFX_INTERFACE_DEFINE_H_

#include <cstdint>
#include <vector>

namespace jf {
struct Adma {
    Adma()
        : message_id(0),
          status_gps_mode(0),
          ins_gnss_ts_msec_epoch(0),
          ins_time_msec(0),
          ins_time_week(0),
          leap_seconds(0),
          start_timestamp_ms_local(0),
          ins_lat_abs(0.0),
          ins_long_abs(0.0),
          ins_height(0.0),
          ins_roll(0.0),
          ins_pitch(0.0),
          ins_yaw(0.0),
          gps_cog(0.0),
          gps_cog_in_enu(0.0),
          ins_vel_frame_x(0.0),
          ins_vel_frame_y(0.0),
          ins_vel_frame_z(0.0),
          ins_vel_hor_x(0.0),
          ins_vel_hor_y(0.0),
          ins_vel_hor_z(0.0),
          acc_hor_x(0.0),
          acc_hor_y(0.0),
          acc_hor_z(0.0),
          turn_lamp_state(0) {}

    uint32_t message_id;                // message identify from 0.
    uint16_t status_gps_mode;           // bit 0 - no GPS - Data available(no GPS augmentation)
                                        // bit 1 - single GPS
                                        // bit 2 - DGPS coarse(pre RTK - Modi)
                                        // bit 3 - DGPS precise - RTK - DGPS - Modus(down to 2cm)
    uint64_t ins_gnss_ts_msec_epoch;    // epoch timestamp
    uint32_t ins_time_msec;             // GNSS UTS time of millisecond from current week
    uint16_t ins_time_week;             // GNSS UTS time of weeks from 0h 6 - jan - 1980
    int16_t leap_seconds;               // leap seconds is using
    uint64_t start_timestamp_ms_local;  // epoch time of system when received
    double ins_lat_abs;                 // Latitude of INS position absolute
    double ins_long_abs;                // Longitude of INS position absolute
    float ins_height;                   // height of INS position
    float ins_roll;                     // INS Angle
    float ins_pitch;                    // INS Angle
    float ins_yaw;                      // INS Angle
    float gps_cog;                      // GPS - Course over ground
    float gps_cog_in_enu;               // GPS - Course over ground in ENU

    // NED coordinate system
    float ins_vel_frame_x;  // X axis points positive to the north
    float ins_vel_frame_y;  // Y axis points positive to the east
    float ins_vel_frame_z;  // Z axis points positive down

    // The axes of the horizontal coordinate system are aligned in such a way that the XY axis level is orthogonal
    // to the acceleration of gravity vector(in the horizon),
    float ins_vel_hor_x;  //
    float ins_vel_hor_y;
    float ins_vel_hor_z;

    // The axes of the horizontal coordinate system are aligned in such a way that the XY axis level is orthogonal
    // to the acceleration of gravity vector(in the horizon),
    float acc_hor_x;
    float acc_hor_y;
    float acc_hor_z;

    // The turn indicator which value definition as below:
    //  0 - default; 1 - turn left; 2 - turn right; 3 - invalid
    uint8_t turn_lamp_state;
};

struct Point3D {
    Point3D() : d_longitude(0.0), d_latitude(0.0), f_altitude(0.0) {}
    Point3D(double lon, double lat, float alt) : d_longitude(lon), d_latitude(lat), f_altitude(alt) {}

    double d_longitude;  // 经度
    double d_latitude;   //纬度
    float f_altitude;    //高度
};

struct LaneEdge {
    LaneEdge() : f_LineLongth(0.0), u8_laneEdgeType(0), u8_laneColor(0), u8_laneEdgeNum(0), u8_laneEdgeIndex(0), u8_laneLeftRoadEdge(0), u8_laneRightRoadEdge(0), EdgeId(0){};

    std::vector<Point3D> edgeGeometry;  // 车道边界线绝对坐标列表，暂时设定500m的数据
    Point3D laneLineChangeStart;        // 车道虚实线信息，起始位置
    Point3D laneLineChangeEnd;          // 车道虚实线信息，终止位置
    float f_LineLongth;                 // 车道虚实线信息，长度
    uint8_t u8_laneEdgeType;            // 线型，0：未知线型；1：实线；2：虚线；3：左虚右实；4：右续左实；5：双实线；6：双虚线；99：其他；
    uint8_t u8_laneColor;               // 颜色，0:未知颜色；1：白色；2：黄色；3：红色；99：其他；
    uint8_t u8_laneEdgeNum;             // 当前Link的车道线总数
    uint8_t u8_laneEdgeIndex;           // 当前车道线为第几条车道线
    uint8_t u8_laneLeftRoadEdge;        // 是否为左边界线，1为是，0为不是
    uint8_t u8_laneRightRoadEdge;       // 是否为右边界线，1为是，0为不是

    uint64_t EdgeId;  //车道边界线编号
};

struct Lane {
    Lane() : f_width(0.0), f_curvature(0.0), f_slope(0.0), u8_turnWaiting(0), u8_laneIndex(0) {}

    std::vector<Point3D> geoLines;  // 车道中心线
    float f_width;                  // 车道宽度
    float f_curvature;              // 曲率
    float f_slope;                  // 坡度
    uint8_t u8_turnWaiting;         // 按位索引组合表达，
                                    // 0x0 : None;
                                    // 0x01 : Straight;
                                    // 0x02 : SlightRight;
                                    // 0x04 : Right;
                                    // 0x08 : HardRight;
                                    // 0x10 : UTurn;
                                    // 0x20 : HardLeft;
                                    // 0x40 : Left;
                                    // 0x80 : SlightLeft;
                                    // 0xFF : NA;
                                    // 备注：目前没有左合流和右合流，使用SlightLeft和SlightRight，以当前数据中有的类型为基础提供此字段。
    uint8_t u8_laneIndex;           // 当前车道为此Link内的第几车道
    uint8_t u8_laneType;            // 0：未调查
                                    // 1：普通车道
                                    // 2：入口车道
                                    // 3：出口车道
                                    // 4：连接车道
                                    // 5：应急车道
                                    // 6：停车道
                                    // 7：紧急停车道
                                    // 8：加速车道
                                    // 9：减速车道
                                    // 10：避险车道
                                    // 11：路口车道
                                    // 14：掉头车道
                                    // 15：公交车道
                                    // 16 潮汐(可变) 车道
                                    // 30：非机动车道
                                    // 99：其它车道
};

struct RoadLink {
    RoadLink() : u8_driveLaneNumber(0), u8_driveRoadProbability(0), u8_TotalLaneNum(0) {}

    std::vector<LaneEdge> edges;      // 车道边界线，当前Link下的车辆位置相关的车道边缘线， 从左（1）往右（N）
    std::vector<Lane> lanes;          // 车道中心线，当前Link下的车辆位置相关的车道中心线， 从左（1）往右（N）
    uint8_t u8_driveLaneNumber;       // Drive lane number of vehicle driving in this link， value : 1 - N
    uint8_t u8_driveRoadProbability;  // Probability of vehicle driving in this link, 0 - 100
    uint8_t u8_TotalLaneNum;          // 当前Link的车道总数
};

struct StopLine {
    StopLine() : bStopLineValidFlag(false), f_stopLineDis(0.0) {}

    bool bStopLineValidFlag;              // 前方行驶道路感知范围内是否有停止线，true：有; false:无
    float f_stopLineDis;                  // 车辆距离当前车道停止线的距离，如当前车道前方无停止线, 单位为米，精确到厘米级别.
    std::vector<Point3D> stopLinePoints;  // 停止线几何点集，通常是一条直线
};

struct PedestrianCrossing {
    PedestrianCrossing() : bPedestrianCrossingValidFlag(false), f_pedestrianCrossingDis(0.0) {}

    bool bPedestrianCrossingValidFlag;                // 前方行驶道路感知范围内是否有人行横道区域，true：有; false:无
    float f_pedestrianCrossingDis;                    // 车辆距离人行横道区域的距离，为沿车道中心线至人行横道面的最近距离, 单位为米，精确到厘米级别.
    std::vector<Point3D> f_pedestrianCrossingPoints;  // 人行横道区域点集
};

struct Crossing {
    Crossing() : bCrossingValidFlag(false), u8_crossingType(0), f_crossingDistance(0) {}

    bool bCrossingValidFlag;             // 前方行驶道路感知范围内是否有交汇路口，true：有; false:无
    uint8_t u8_crossingType;             // 预留字段，暂无具体含义，赋值为0
    float f_crossingDistance;            // 车辆位置到交汇路口起始点的距离, 单位为米，精确到厘米级别.
    std::vector<Point3D> geoAreaPoints;  // 交叉路口大致轮廓， 控制在100个点以内。
};

struct Ramp {
    Ramp() : bRampValidFlag(false), u8_rampType(5), f_rampStartPointDis(0.0), f_rampEndPointDis(0.0) {}

    bool bRampValidFlag;              // 前方行驶道路感知范围内是否有匝道，true：有; false:无
    uint8_t u8_rampType;              // 匝道类型，0x0: ramp out；0x1:ramp in; 0x2:split; 0x03:Merge; 0x5: Reserved
    float f_rampStartPointDis;        // 车辆离匝道交汇起始点的距离,单位为米，精确到厘米级别.
    float f_rampEndPointDis;          // 车辆离匝道交汇终点的距离,单位为米，精确到厘米级别.
    Point3D rampStartPoint;           // 起点
    Point3D rampEndPoint;             // 终点
    std::vector<LaneEdge> rampEdges;  // 出入口道路的车道线信息
};

struct Change {
    Change() : bChangeValidFlag(false), i32_changeType(0), f_changeDistance(0.0) {}

    bool bChangeValidFlag;   // 前方行驶道路感知范围内是否有车道变化，true：有; false:无
    int32_t i32_changeType;  // 车道数量变化类型，增多或者减少
    float f_changeDistance;  // 车辆到车道数变化点的道路距离，以当前车道到变化点所在link的终点为准,单位为米，精确到厘米级别.
    Point3D changePoint;     // 车道数量变化点
};

struct Speed {
    Speed() : bSpeedLimitValidFlag(false), u16_CurrentRoadSDLimit_Max(0), u16_CurrentRoadSDLimit_Min(0), u16_NextRoadSDLimit_Max(0), u6_NextRoadSDLimit_Min(0), f_distanceToNextSpeedLimit(0.0) {}

    bool bSpeedLimitValidFlag;            // 前方行驶道路感知范围内是否有限速，true：有; false : 无
    uint16_t u16_CurrentRoadSDLimit_Max;  // 当前道路的最大限速，0表示无效值
    uint16_t u16_CurrentRoadSDLimit_Min;  // 当前道路的最低限速（仅高速公路有效), 0表示无效值
    uint16_t u16_NextRoadSDLimit_Max;     // 下段路的最大限速, 0表示无效值
    uint16_t u6_NextRoadSDLimit_Min;      // 下段路的最低限速（仅高速公路有效）, 0表示无效值
    float f_distanceToNextSpeedLimit;     // 车辆到下一个限速变化起点的道路距离,单位为米，精确到厘米级别.
};

struct TrafficLight {
    TrafficLight() : bTrafficLightValidFlag(false), f_distanceToTrafficLight(0.0) {}

    bool bTrafficLightValidFlag;     // 前方行驶道路感知范围内是否有红绿灯，true：有; false:无
    Point3D trafficLightLoc;         // 位置
    float f_distanceToTrafficLight;  // 道路距离,单位为米，精确到厘米级别.
};

struct RSU {
    RSU() : bRsuValidFlag(false), f_distanceToRsu(0.0) {}

    bool bRsuValidFlag;     // 前方行驶道路感知范围内是否有RSU，true：有; false:无
    Point3D rsuLocation;    // 位置
    float f_distanceToRsu;  // 直线距离，直接用经纬度计算,单位为米，精确到厘米级别.
};

struct Tunnel {
    Tunnel() : bTunnelValidFlag(false), u8_TunnelType(0), f_distanceToTunnel(0.0), f_tunnel_length(0.0) {}

    bool bTunnelValidFlag;     // 前方感知范围内是否有隧道，true：有隧道; false:无隧道
    uint8_t u8_TunnelType;     // 类型，默认赋0,，暂无含义
    float f_distanceToTunnel;  // 车辆位置到隧道起始点的距离,单位为米，精确到厘米级别.
    float f_tunnel_length;     // 隧道长度,单位为米，精确到厘米级别.
    Point3D startPoint;        // 车辆行驶方向的起始位置
    Point3D endPoint;          // 车辆行驶方向的结束位置
};

struct Road {
    Road() : u8_CurrentLane(0), f_dashSolidChangeDis(0) {}

    std::vector<RoadLink> roadLinks;        // 道路Link信息，由车道边界线和车道中心线组成，用来表达Link的连续关系
    StopLine stopLine;                      // 停止线信息
    PedestrianCrossing pedestrianCrossing;  // 人行横道区域
    Crossing crossing;                      // 交叉路口信息
    Ramp ramp;                              // 匝道
    Change changePoint;                     // 车道变化点
    Speed speed;                            // 车道的速度信息
    TrafficLight trafficLight;              // 交通信号灯, 如无则数组长度为0
    RSU rsu;                                // RSU信号杆, 如无则数组长度为0， 行驶道路上的RSU， 按实际距离排序
    Tunnel tunnel;                          // 隧道信息
    uint8_t u8_CurrentLane;                 // 车辆所在当前车道， 从左（1）往右（N）
    float f_dashSolidChangeDis;             // 车辆距离无道路分歧的虚实线变化点的距离，如无则填 - 1, 单位为米，精确到厘米级别.
};

struct Gnss {
    Gnss()
        : u64_time_msec(0),
          u64_time_week(0),
          u64_EpochTimestamp(0),
          f_pitch(0.0),
          f_roll(0.0),
          f_yaw(0.0),
          f_acceleX(0.0),
          f_acceleY(0.0),
          f_acceleZ(0.0),
          u8_turnLampState(0),
          u64_AdmaMsgReceivedTime(0),
          u64_SensorNodeProcessTime(0),
          u64_MapProcessTime(0) {}

    uint64_t u64_time_msec;       // GNSS UTS time of millisecond  from current week
    uint64_t u64_time_week;       // GNSS UTS time of weeks from 0h 6-jan-1980
    uint64_t u64_EpochTimestamp;  // epoch timestamp in millisecond base on GPS UTC time

    Point3D locationRel;  // 相对坐标
    Point3D locationAbs;  // 绝对坐标

    float f_pitch;  // pitch angle
    float f_roll;   // roll angle
    float f_yaw;    // yaw angle

    float f_acceleX;  // acceleration of x
    float f_acceleY;  // acceleration of y
    float f_acceleZ;  // acceleration of z

    uint8_t u8_turnLampState;  // 0 - default; 1 - turn left; 2 - turn right; 3 - invalid

    uint64_t u64_AdmaMsgReceivedTime;    // ROS system time when received ADMA message in sensor node
    uint64_t u64_SensorNodeProcessTime;  // Process time in sensor node, current_time - AdmaMsgReceivedTime
    uint64_t u64_MapProcessTime;         // Process time in map engine / software
};

struct MapData {
    MapData() : bOnMapFlag(false) {}

    Road road;        // road msg
    bool bOnMapFlag;  // The flag of on map
    Gnss gnssInfo;    // vehicle GNSS information
};

}  // namespace jf

#endif  // _JFX_INTERFACE_DEFINE_H_