package main

import (
	"crypto/sha1"
	"encoding/hex"
	"fmt"

	parser "github.com/openvenues/gopostal/parser"
)

type Address struct {
	ID           string `json:"id"`
	Country      string `json:"country"`
	State        string `json:"state"`
	City         string `json:"city"`
	Neighborhood string `json:"neighborhood"`
	Road         string `json:"road"`
	HouseNumber  string `json:"house_number"`
	House        string `json:"house"`
	Unit         string `json:"unit"`
	PostalCode   string `json:"postal_code"`
	Raw          string `json:"raw_address"`
}

func (a Address) String() string {
	return fmt.Sprintf(
		"%s, %s, %s %s. %s, %s, %s, %s.",
		a.Road,
		a.HouseNumber,
		a.Unit,
		a.House,
		a.Neighborhood,
		a.City,
		a.State,
		a.PostalCode,
	)
}

func (a Address) id() string {
	hasher := sha1.New()
	hasher.Write([]byte(a.String()))
	return hex.EncodeToString(hasher.Sum(nil))
}

func parseAddress(address string) Address {
	// log.Printf("Address to parse: %s", address)
	components := parser.ParseAddress(address)
	// log.Printf("Address components: %s", components)
	return newFromComponents(address, components)
}

func newFromComponents(raw string, components []parser.ParsedComponent) Address {
	address := Address{Raw: raw}
	for _, component := range components {
		switch component.Label {
		case "house":
			address.House = component.Value
		case "house_number":
			address.HouseNumber = component.Value
		case "road":
			address.Road = component.Value
		case "unit":
			address.Unit = component.Value
		case "postcode":
			address.PostalCode = component.Value
		case "suburb":
			address.Neighborhood = component.Value
		case "city_district":
			address.Neighborhood = component.Value
		case "city":
			address.City = component.Value
		case "state_district":
			address.Neighborhood = component.Value
		case "state":
			address.State = component.Value
		case "country":
			address.Country = component.Value
		}
	}
	address.ID = address.id()
	// log.Printf("Address parsed: %s", address)
	return address
}
