package main

import (
	"fmt"
	"math"
	"strings"
)

func myAtoi(str string) int {
	str = strings.Trim(str, " ")
	if len(str) == 0 {
		return 0
	}
	chars := []rune(str)
	beg, end := 0, 0
	isNegative := false
	// judge the sign of the integer
	switch chars[beg] {
	case '-':
		isNegative = true
		fallthrough
	case '+':
		beg, end = 1, 1
		// deal with "+" or "-"
		if len(str) == 1 {
			return 0
		}
	default:
		beg, end = 0, 0
	}
	// find the first non-zero digit and the last valid digit
	for ; end <= len(chars); end++ {
		if chars[beg] == '0' {
			beg++
			// for str like "000000000000", return 0
			if beg == len(chars) {
				return 0
			}
			continue
		}
		if end == len(chars) || chars[end] < '0' || '9' < chars[end] {
			break
		}
	}
	if beg == end {
		// no valid digit
		return 0
	} else if end-beg > 10 { // overflow (MaxInt32 & MinInt32 have 10 digits only)
		if isNegative {
			return math.MinInt32
		}
		return math.MaxInt32
	}
	sum, base := int64(0), int64(1)
	for ; end > beg; end-- {
		num := int64(chars[end-1] - '0')
		sum += num * base
		base *= int64(10)
	}
	if isNegative {
		sum *= int64(-1)
	}
	if sum < math.MinInt32 {
		return math.MinInt32
	} else if sum > math.MaxInt32 {
		return math.MaxInt32
	}
	return int(sum)
}

func testMyAtoi(str string) {
	fmt.Printf("\"%s\" -> %d\n", str, myAtoi(str))
}

/* func main() {
	testMyAtoi("")
	testMyAtoi("       00000000000000000000           ")
	testMyAtoi("+")
	testMyAtoi("   -0.1    ")
	testMyAtoi("   +1.1    ")
	testMyAtoi("   234.1    ")
	testMyAtoi("42")
	testMyAtoi("9223372036854775808")
	testMyAtoi("   -2.1    ")
	testMyAtoi("   - 0.1    ")
	testMyAtoi("   num 0.1    ")
} */