// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package cookiejar

// This file implements the Punycode algorithm from RFC 3492.

import (
	
	
	
	
)

// These parameter values are specified in section 5.
//
// All computation is done with int32s, so that overflow behavior is identical
// regardless of whether int is 32-bit or 64-bit.
const (
	base        int32 = 36
	damp        int32 = 700
	initialBias int32 = 72
	initialN    int32 = 128
	skew        int32 = 38
	tmax        int32 = 26
	tmin        int32 = 1
)

// encode encodes a string as specified in section 6.3 and prepends prefix to
// the result.
//
// The "while h < length(input)" line in the specification becomes "for
// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes.
func encode(,  string) (string, error) {
	 := make([]byte, len(), len()+1+2*len())
	copy(, )
	, ,  := int32(0), initialN, initialBias
	,  := int32(0), int32(0)
	for ,  := range  {
		if  < utf8.RuneSelf {
			++
			 = append(, byte())
		} else {
			++
		}
	}
	 := 
	if  > 0 {
		 = append(, '-')
	}
	for  != 0 {
		 := int32(0x7fffffff)
		for ,  := range  {
			if  >  &&  >=  {
				 = 
			}
		}
		 += ( - ) * ( + 1)
		if  < 0 {
			return "", fmt.Errorf("cookiejar: invalid label %q", )
		}
		 = 
		for ,  := range  {
			if  <  {
				++
				if  < 0 {
					return "", fmt.Errorf("cookiejar: invalid label %q", )
				}
				continue
			}
			if  >  {
				continue
			}
			 := 
			for  := base; ;  += base {
				 :=  - 
				if  < tmin {
					 = tmin
				} else if  > tmax {
					 = tmax
				}
				if  <  {
					break
				}
				 = append(, encodeDigit(+(-)%(base-)))
				 = ( - ) / (base - )
			}
			 = append(, encodeDigit())
			 = adapt(, +1,  == )
			 = 0
			++
			--
		}
		++
		++
	}
	return string(), nil
}

func encodeDigit( int32) byte {
	switch {
	case 0 <=  &&  < 26:
		return byte( + 'a')
	case 26 <=  &&  < 36:
		return byte( + ('0' - 26))
	}
	panic("cookiejar: internal error in punycode encoding")
}

// adapt is the bias adaptation function specified in section 6.1.
func adapt(,  int32,  bool) int32 {
	if  {
		 /= damp
	} else {
		 /= 2
	}
	 +=  / 
	 := int32(0)
	for  > ((base-tmin)*tmax)/2 {
		 /= base - tmin
		 += base
	}
	return  + (base-tmin+1)*/(+skew)
}

// Strictly speaking, the remaining code below deals with IDNA (RFC 5890 and
// friends) and not Punycode (RFC 3492) per se.

// acePrefix is the ASCII Compatible Encoding prefix.
const acePrefix = "xn--"

// toASCII converts a domain or domain label to its ASCII form. For example,
// toASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
// toASCII("golang") is "golang".
func toASCII( string) (string, error) {
	if ascii.Is() {
		return , nil
	}
	 := strings.Split(, ".")
	for ,  := range  {
		if !ascii.Is() {
			,  := encode(acePrefix, )
			if  != nil {
				return "", 
			}
			[] = 
		}
	}
	return strings.Join(, "."), nil
}