package binres

import (
	"archive/zip"
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"os"
	"path/filepath"

	"golang.org/x/mobile/internal/sdkpath"
)

// MinSDK is the targeted sdk version for support by package binres.
const MinSDK = 16

func apiResources() ([]byte, error) {
	apiResPath, err := apiResourcesPath()
	if err != nil {
		return nil, err
	}
	zr, err := zip.OpenReader(apiResPath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, fmt.Errorf(`%v; consider installing with "android update sdk --all --no-ui --filter android-%d"`, err, MinSDK)
		}
		return nil, err
	}
	defer zr.Close()

	buf := new(bytes.Buffer)
	for _, f := range zr.File {
		if f.Name == "resources.arsc" {
			rc, err := f.Open()
			if err != nil {
				return nil, err
			}
			_, err = io.Copy(buf, rc)
			if err != nil {
				return nil, err
			}
			rc.Close()
			break
		}
	}
	if buf.Len() == 0 {
		return nil, fmt.Errorf("failed to read resources.arsc")
	}
	return buf.Bytes(), nil
}

func apiResourcesPath() (string, error) {
	platformDir, err := sdkpath.AndroidAPIPath(MinSDK)
	if err != nil {
		return "", err
	}
	return filepath.Join(platformDir, "android.jar"), nil
}

// PackResources produces a stripped down gzip version of the resources.arsc from api jar.
func PackResources() ([]byte, error) {
	tbl, err := OpenSDKTable()
	if err != nil {
		return nil, err
	}

	tbl.pool.strings = []string{} // should not be needed
	pkg := tbl.pkgs[0]

	// drop language string entries
	for _, typ := range pkg.specs[3].types {
		if typ.config.locale.language != 0 {
			for j, nt := range typ.entries {
				if nt == nil { // NoEntry
					continue
				}
				pkg.keyPool.strings[nt.key] = ""
				typ.indices[j] = NoEntry
				typ.entries[j] = nil
			}
		}
	}

	// drop strings from pool for specs to be dropped
	for _, spec := range pkg.specs[4:] {
		for _, typ := range spec.types {
			for _, nt := range typ.entries {
				if nt == nil { // NoEntry
					continue
				}
				// don't drop if there's a collision
				var collision bool
				for _, xspec := range pkg.specs[:4] {
					for _, xtyp := range xspec.types {
						for _, xnt := range xtyp.entries {
							if xnt == nil {
								continue
							}
							if collision = nt.key == xnt.key; collision {
								break
							}
						}
					}
				}
				if !collision {
					pkg.keyPool.strings[nt.key] = ""
				}
			}
		}
	}

	// entries are densely packed but probably safe to drop nil entries off the end
	for _, spec := range pkg.specs[:4] {
		for _, typ := range spec.types {
			var last int
			for i, nt := range typ.entries {
				if nt != nil {
					last = i
				}
			}
			typ.entries = typ.entries[:last+1]
			typ.indices = typ.indices[:last+1]
		}
	}

	// keeping 0:attr, 1:id, 2:style, 3:string
	pkg.typePool.strings = pkg.typePool.strings[:4]
	pkg.specs = pkg.specs[:4]

	bin, err := tbl.MarshalBinary()
	if err != nil {
		return nil, err
	}

	buf := new(bytes.Buffer)

	zw := gzip.NewWriter(buf)
	if _, err := zw.Write(bin); err != nil {
		return nil, err
	}
	if err := zw.Flush(); err != nil {
		return nil, err
	}
	if err := zw.Close(); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}
