/* Copyright 2017 The Bazel Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package rule

import (
	"sort"
	"strings"

	bzl "github.com/bazelbuild/buildtools/build"
)

// PlatformConstraint represents a constraint_setting target for a particular
// OS/arch combination.
//
// DEPRECATED: do not use outside language/go.
type PlatformConstraint struct {
	Platform
	ConstraintPrefix string
}

func (p PlatformConstraint) String() string {
	pStr := p.Platform.String()
	if pStr == "" {
		return ""
	}
	return p.ConstraintPrefix + pStr
}

// PlatformStrings contains a set of strings associated with a buildable
// target in a package. This is used to store source file names,
// import paths, and flags.
//
// Strings are stored in four sets: generic strings, OS-specific strings,
// arch-specific strings, and OS-and-arch-specific strings. A string may not
// be duplicated within a list or across sets; however, a string may appear
// in more than one list within a set (e.g., in "linux" and "windows" within
// the OS set). Strings within each list should be sorted, though this may
// not be relied upon.
//
// DEPRECATED: do not use outside language/go. This type is Go-specific and
// should be moved to the Go extension.
type PlatformStrings struct {
	// Generic is a list of strings not specific to any platform.
	Generic []string

	// OS is a map from an OS constraint to OS-specific strings.
	OS map[string][]string

	// Arch is a map from an architecture constraint to
	// architecture-specific strings.
	Arch map[string][]string

	// Platform is a map from platform constraints to OS and
	// architecture-specific strings.
	Platform map[PlatformConstraint][]string
}

var _ BzlExprValue = (*PlatformStrings)(nil)

// HasExt returns whether this set contains a file with the given extension.
func (ps *PlatformStrings) HasExt(ext string) bool {
	return ps.firstExtFile(ext) != ""
}

func (ps *PlatformStrings) IsEmpty() bool {
	return len(ps.Generic) == 0 && len(ps.OS) == 0 && len(ps.Arch) == 0 && len(ps.Platform) == 0
}

// Flat returns all the strings in the set, sorted and de-duplicated.
func (ps *PlatformStrings) Flat() []string {
	unique := make(map[string]struct{})
	for _, s := range ps.Generic {
		unique[s] = struct{}{}
	}
	for _, ss := range ps.OS {
		for _, s := range ss {
			unique[s] = struct{}{}
		}
	}
	for _, ss := range ps.Arch {
		for _, s := range ss {
			unique[s] = struct{}{}
		}
	}
	for _, ss := range ps.Platform {
		for _, s := range ss {
			unique[s] = struct{}{}
		}
	}
	flat := make([]string, 0, len(unique))
	for s := range unique {
		flat = append(flat, s)
	}
	sort.Strings(flat)
	return flat
}

func (ps *PlatformStrings) firstExtFile(ext string) string {
	for _, f := range ps.Generic {
		if strings.HasSuffix(f, ext) {
			return f
		}
	}
	for _, fs := range ps.OS {
		for _, f := range fs {
			if strings.HasSuffix(f, ext) {
				return f
			}
		}
	}
	for _, fs := range ps.Arch {
		for _, f := range fs {
			if strings.HasSuffix(f, ext) {
				return f
			}
		}
	}
	for _, fs := range ps.Platform {
		for _, f := range fs {
			if strings.HasSuffix(f, ext) {
				return f
			}
		}
	}
	return ""
}

// Map applies a function that processes individual strings to the strings
// in "ps" and returns a new PlatformStrings with the result. Empty strings
// returned by the function are dropped.
func (ps *PlatformStrings) Map(f func(s string) (string, error)) (PlatformStrings, []error) {
	var errors []error
	mapSlice := func(ss []string) ([]string, error) {
		rs := make([]string, 0, len(ss))
		for _, s := range ss {
			if r, err := f(s); err != nil {
				errors = append(errors, err)
			} else if r != "" {
				rs = append(rs, r)
			}
		}
		return rs, nil
	}
	result, _ := ps.MapSlice(mapSlice)
	return result, errors
}

// MapSlice applies a function that processes slices of strings to the strings
// in "ps" and returns a new PlatformStrings with the results.
func (ps *PlatformStrings) MapSlice(f func([]string) ([]string, error)) (PlatformStrings, []error) {
	var errors []error

	mapSlice := func(ss []string) []string {
		rs, err := f(ss)
		if err != nil {
			errors = append(errors, err)
			return nil
		}
		return rs
	}

	mapStringMap := func(m map[string][]string) map[string][]string {
		if m == nil {
			return nil
		}
		rm := make(map[string][]string)
		for k, ss := range m {
			ss = mapSlice(ss)
			if len(ss) > 0 {
				rm[k] = ss
			}
		}
		if len(rm) == 0 {
			return nil
		}
		return rm
	}

	mapPlatformMap := func(m map[PlatformConstraint][]string) map[PlatformConstraint][]string {
		if m == nil {
			return nil
		}
		rm := make(map[PlatformConstraint][]string)
		for k, ss := range m {
			ss = mapSlice(ss)
			if len(ss) > 0 {
				rm[k] = ss
			}
		}
		if len(rm) == 0 {
			return nil
		}
		return rm
	}

	result := PlatformStrings{
		Generic:  mapSlice(ps.Generic),
		OS:       mapStringMap(ps.OS),
		Arch:     mapStringMap(ps.Arch),
		Platform: mapPlatformMap(ps.Platform),
	}
	return result, errors
}

func (ps PlatformStrings) BzlExpr() bzl.Expr {
	var pieces []bzl.Expr
	if len(ps.Generic) > 0 {
		pieces = append(pieces, ExprFromValue(ps.Generic))
	}
	if len(ps.OS) > 0 {
		pieces = append(pieces, platformStringsOSArchDictExpr(ps.OS))
	}
	if len(ps.Arch) > 0 {
		pieces = append(pieces, platformStringsOSArchDictExpr(ps.Arch))
	}
	if len(ps.Platform) > 0 {
		pieces = append(pieces, platformStringsPlatformDictExpr(ps.Platform))
	}
	if len(pieces) == 0 {
		return &bzl.ListExpr{}
	} else if len(pieces) == 1 {
		return pieces[0]
	} else {
		e := pieces[0]
		if list, ok := e.(*bzl.ListExpr); ok {
			list.ForceMultiLine = true
		}
		for _, piece := range pieces[1:] {
			e = &bzl.BinaryExpr{X: e, Y: piece, Op: "+"}
		}
		return e
	}
}

func platformStringsOSArchDictExpr(m map[string][]string) bzl.Expr {
	s := make(SelectStringListValue)
	for key, value := range m {
		s[key] = value
	}
	s["//conditions:default"] = nil
	return s.BzlExpr()
}

func platformStringsPlatformDictExpr(m map[PlatformConstraint][]string) bzl.Expr {
	s := make(SelectStringListValue)
	for key, value := range m {
		s[key.String()] = value
	}
	s["//conditions:default"] = nil
	return s.BzlExpr()
}
