package main

import (
	"bytes"
	"encoding/json"
	"fmt"
)

type myStruct struct {
	Name   string
	Age    int
	Status bool
	Values []int
}

func main() {
	// foo1()
	// decodeJson()
	// testJson()
	// foo2()
	annotation()
}

func foo1() {
	s := myStruct{
		Name:   "John Connor",
		Age:    35,
		Status: true,
		Values: []int{15, 11, 37},
	}

	data, err := json.Marshal(s)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Printf("%s", data)

	newData, err := json.MarshalIndent(s, "", "\t")
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Printf("%s", newData)
}

func decodeJson() {
	data := []byte(`{"Name":"John Connor","Age":35,"Status":true,"Values":[15,11,37]}`)

	var s myStruct

	if err := json.Unmarshal(data, &s); err != nil {
		fmt.Println(err)
		return
	}

	fmt.Printf("%v", s)
}

// Проверка JSON на правильность.
// Можем проверить является ли срез байтов форматом json.
func testJson() {
	type user struct {
		Name     string
		Email    string
		Status   bool
		Language []byte
	}

	m := user{Name: "John Connor", Email: "test email"}

	data, _ := json.Marshal(m)

	data = bytes.Trim(data, "{")

	if !json.Valid(data) {
		fmt.Println("invalid json!")
	}

	fmt.Printf("%s", data)
}

func foo2() {

	type user struct {
		Name     string
		Email    string
		Status   bool
		Language []byte
	}

	newUser := user{
		Name:     "Alex",
		Email:    "email@email.email",
		Status:   true,
		Language: []byte("ru"),
	}

	data, err := json.Marshal(newUser)
	if err != nil {
		panic(err)
	}

	newUser.Language = []byte("en")
	err = json.Unmarshal(data, &newUser)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(newUser.Language))
	// fmt.Println(data)
	// fmt.Printf("%s", data)
}

func annotation() {
	type myStruct struct {
		// при кодировании / декодировании будет использовано имя name, а не Name
		Name string `json:"name"`

		// при кодировании / декодировании будет использовано то же имя (Age),
		// но если значение поля равно 0 (пустое значение: false, nil, пустой слайс и пр.),
		// то при кодировании оно будет опущено
		Age int `json:",omitempty"`

		// при кодировании . декодировании поле всегда игнорируется
		Status bool `json:"-"`
	}

	m := myStruct{Name: "John Connor", Age: 0, Status: true}

	data, err := json.Marshal(m)

	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Printf("%s", data) //
}
