package srt

import (
	"fmt"
	"strings"
)

type streamIDMode int

const (
	streamIDModeRead streamIDMode = iota
	streamIDModePublish
)

type streamID struct {
	mode  streamIDMode
	path  string
	query string
	user  string
	pass  string
}

func (s *streamID) unmarshal(raw string) error {
	// standard syntax
	// https://github.com/Haivision/srt/blob/master/docs/features/access-control.md
	if strings.HasPrefix(raw, "#!::") {
		for _, kv := range strings.Split(raw[len("#!::"):], ",") {
			kv2 := strings.SplitN(kv, "=", 2)
			if len(kv2) != 2 {
				return fmt.Errorf("invalid value")
			}

			key, value := kv2[0], kv2[1]

			switch key {
			case "u":
				s.user = value

			case "r":
				s.path = value

			case "h":

			case "s":
				s.pass = value

			case "t":

			case "m":
				switch value {
				case "request":
					s.mode = streamIDModeRead

				case "publish":
					s.mode = streamIDModePublish

				default:
					return fmt.Errorf("unsupported mode '%s'", value)
				}
			}
		}
	} else {
		parts := strings.Split(raw, ":")
		if len(parts) < 2 || len(parts) > 5 {
			return fmt.Errorf("stream ID must be 'action:pathname[:query]' or 'action:pathname:user:pass[:query]', " +
				"where action is either read or publish, pathname is the path name, user and pass are the credentials, " +
				"query is an optional token containing additional information")
		}

		switch parts[0] {
		case "read":
			s.mode = streamIDModeRead

		case "publish":
			s.mode = streamIDModePublish

		default:
			return fmt.Errorf("stream ID must be 'action:pathname[:query]' or 'action:pathname:user:pass[:query]', " +
				"where action is either read or publish, pathname is the path name, user and pass are the credentials, " +
				"query is an optional token containing additional information")
		}

		s.path = parts[1]

		if len(parts) == 4 || len(parts) == 5 {
			s.user, s.pass = parts[2], parts[3]
		}

		if len(parts) == 3 {
			s.query = parts[2]
		} else if len(parts) == 5 {
			s.query = parts[4]
		}
	}

	return nil
}
