/* 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
}

// 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()
}
