#ifndef STORAGE_LEVELDB_UTIL_SERIALIZE_VALUE_H_
#define STORAGE_LEVELDB_UTIL_SERIALIZE_VALUE_H_

#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include <map>
#include "leveldb/slice.h"
#include "util/coding.h"
namespace leveldb{
using Field = std::pair<std::string, std::string>;	  // field_name:field_value
using FieldArray = std::vector<std::pair<std::string, std::string>>;
using FieldSliceArray = std::vector<std::pair<Slice, Slice>>;

std::string SerializeValue(const FieldArray& fields);
std::string SerializeValue(const FieldSliceArray& fields);
FieldArray *ParseValue(const std::string& value_str, FieldArray *fields);

class InternalFieldArray {
public:
    using FieldMap = std::map<std::string,Slice>;

    InternalFieldArray(const FieldArray &fields, bool to_map = false):
                        fields(fields),isMapped(false) {
        if(to_map) Map();
    }


    InternalFieldArray(const Slice value_slice) {
        Slice valueSlice = value_slice;
        Slice nameSlice, valSlice;
        while(GetLengthPrefixedSlice(&valueSlice, &nameSlice)) {
            if(GetLengthPrefixedSlice(&valueSlice, &valSlice)) {
                map[nameSlice.ToString()] = valSlice;
            } else {
                std::cout << "name and val not match! From InternalFieldArray" << std::endl;
            }
            nameSlice.clear();
            valSlice.clear();
        }
        isMapped = true;
    }

    InternalFieldArray(const std::string& value_str) 
                    :leveldb::InternalFieldArray(Slice(value_str)) {}

    //将vector变为用map存
    void Map();

    std::string Serialize();

    bool HasField(const Field& field);
    Slice ValOfName(const std::string& name);

private:
    bool isMapped;
    const FieldArray fields;
    FieldMap map;
};
}
#endif