// Copyright 2018 The Fuchsia 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 system_updater

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"syscall/zx"

	"app/context"
	fuchsiaio "fidl/fuchsia/io"
	"fidl/fuchsia/pkg"
	"syslog/logger"
)

type Package struct {
	namever string
	merkle  string
}

func ConnectToPackageResolver() (*pkg.PackageResolverInterface, error) {
	context := context.CreateFromStartupInfo()
	req, pxy, err := pkg.NewPackageResolverInterfaceRequest()

	if err != nil {
		logger.Errorf("control interface could not be acquired: %s", err)
		return nil, err
	}

	context.ConnectToEnvService(req)
	return pxy, nil
}

func ParseRequirements(pkgSrc io.ReadCloser, imgSrc io.ReadCloser) ([]*Package, []string, error) {
	imgs := []string{}
	pkgs := []*Package{}

	rdr := bufio.NewReader(pkgSrc)
	for {
		l, err := rdr.ReadString('\n')
		s := strings.TrimSpace(l)
		if (err == nil || err == io.EOF) && len(s) > 0 {
			entry := strings.Split(s, "=")
			if len(entry) != 2 {
				return nil, nil, fmt.Errorf("parser: entry format %q", s)
			} else {
				pkgs = append(pkgs, &Package{namever: entry[0], merkle: entry[1]})
			}
		}

		if err != nil {
			if err != io.EOF {
				return nil, nil, fmt.Errorf("parser: got error reading packages file %s", err)
			}
			break
		}
	}

	rdr = bufio.NewReader(imgSrc)

	for {
		l, err := rdr.ReadString('\n')
		s := strings.TrimSpace(l)
		if (err == nil || err == io.EOF) && len(s) > 0 {
			imgs = append(imgs, s)
		}

		if err != nil {
			if err != io.EOF {
				return nil, nil, fmt.Errorf("parser: got error reading images file %s", err)
			}
			break
		}
	}

	return pkgs, imgs, nil
}

func FetchPackages(pkgs []*Package, resolver *pkg.PackageResolverInterface) error {
	var errCount int
	for _, pkg := range pkgs {
		if err := fetchPackage(pkg, resolver); err != nil {
			logger.Errorf("fetch error: %s", err)
			errCount++
		}
	}

	if errCount > 0 {
		return fmt.Errorf("system update failed, %d packages had errors", errCount)
	}

	return nil
}

func fetchPackage(p *Package, resolver *pkg.PackageResolverInterface) error {
	b, err := ioutil.ReadFile(filepath.Join("/pkgfs/packages", p.namever, "meta"))
	if err == nil {
		// package is already installed, skip
		if string(b) == p.merkle {
			return nil
		}
	}

	pkgUri := fmt.Sprintf("fuchsia-pkg://fuchsia.com/%s?hash=%s", p.namever, p.merkle)
	selectors := []string{}
	updatePolicy := pkg.UpdatePolicy{}
	dirReq, dirPxy, err := fuchsiaio.NewDirectoryInterfaceRequest()
	defer dirPxy.Close()

	logger.Infof("requesting %s from update system", pkgUri)

	status, err := resolver.Resolve(pkgUri, selectors, updatePolicy, dirReq)
	if err != nil {
		return fmt.Errorf("fetch: Resolve error: %s", err)
	}

	statusErr := zx.Status(status)
	if statusErr != zx.ErrOk {
		return fmt.Errorf("fetch: Resolve status: %s", statusErr)
	}

	return nil
}

var diskImagerPath = filepath.Join("/pkg", "bin", "install-disk-image")

func ValidateImgs(imgs []string, imgsPath string) error {
	boardPath := filepath.Join(imgsPath, "board")
	actual, err := ioutil.ReadFile(boardPath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		} else {
			return err
		}
	}
	expected, err := ioutil.ReadFile("/config/build-info/board")
	if err != nil {
		return err
	}
	if !bytes.Equal(actual, expected) {
		return fmt.Errorf("parser: expected board name %s found %s", expected, actual)
	}
	return nil
}

func WriteImgs(imgs []string, imgsPath string) error {
	logger.Infof("Writing images %+v from %q", imgs, imgsPath)

	for _, img := range imgs {
		imgPath := filepath.Join(imgsPath, img)
		if fi, err := os.Stat(imgPath); err != nil || fi.Size() == 0 {
			logger.Warnf("img_writer: %q image not found or zero length, skipping", img)
			continue
		}

		var c *exec.Cmd
		switch img {
		case "zbi", "zbi.signed":
			c = exec.Command(diskImagerPath, "install-zircona")
		case "zedboot", "zedboot.signed":
			c = exec.Command(diskImagerPath, "install-zirconr")
			// TODO(ZX-2689): remove once the bootloader is booting zirconr as recovery.
			if img == "zedboot.signed" {
				c = exec.Command(diskImagerPath, "install-zirconb")
			}
		case "bootloader":
			c = exec.Command(diskImagerPath, "install-bootloader")
		case "board":
			continue
		default:
			return fmt.Errorf("unrecognized image %q", img)
		}

		logger.Infof("img_writer: writing %q from %q", img, imgPath)
		out, err := writeImg(c, imgPath)
		if len(out) != 0 {
			logger.Infof("img_writer: %s", string(out))
		}
		if err != nil {
			logger.Errorf("img_writer: error writing %q from %q: %s", img, imgPath, err)
			if len(out) != 0 {
				logger.Errorf("img_writer: %s", string(out))
			}
			return err
		}
		logger.Infof("img_writer: wrote %q successfully from %q", img, imgPath)
	}
	return nil
}

func writeImg(c *exec.Cmd, path string) ([]byte, error) {
	info, err := os.Stat(path)
	if err != nil {
		return nil, err
	}
	if info.Size() == 0 {
		return nil, fmt.Errorf("img_writer: image file is empty!")
	}
	imgFile, err := os.Open(path)
	if err != nil {
		return nil, err
	}

	defer imgFile.Close()
	c.Stdin = imgFile

	return c.CombinedOutput()
}

// UpdateCurrentChannel persists the update channel info for a successful update
func UpdateCurrentChannel() error {
	targetPath := "/misc/ota/target_channel.json"
	contents, err := ioutil.ReadFile(targetPath)
	if err != nil {
		return fmt.Errorf("no target channel recorded in %v: %v", targetPath, err)
	}
	currentPath := "/misc/ota/current_channel.json"
	partPath := currentPath + ".part"
	f, err := os.Create(partPath)
	if err != nil {
		return fmt.Errorf("unable to write current channel to %v: %v", partPath, err)
	}
	defer f.Close()
	buf := bytes.NewBuffer(contents)
	_, err = buf.WriteTo(f)
	if err != nil {
		return fmt.Errorf("unable to write current channel to %v: %v", currentPath, err)
	}
	f.Sync()
	f.Close()
	if err := os.Rename(partPath, currentPath); err != nil {
		return fmt.Errorf("error moving %v to %v: %v", partPath, currentPath, err)
	}
	return nil
}
