// Copyright 2018 Google LLC
//
// 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 config exports functionality for storing/retrieving build step configuration on/from
// the local disk.
package config

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"

	"cos.googlesource.com/cos/tools.git/src/pkg/utils"
	compute "google.golang.org/api/compute/v1"
)

// Image stores GCE image configuration.
type Image struct {
	*compute.Image
	Project string
}

// NewImage builds an Image with some initialized defaults.
func NewImage(name string, project string) *Image {
	return &Image{
		&compute.Image{Name: name, Labels: make(map[string]string)},
		project,
	}
}

// URL gets the partial GCE URL of the image.
func (i *Image) URL() string {
	return fmt.Sprintf("projects/%s/global/images/%s", i.Project, i.Name)
}

// MarshalJSON marshals the image configuration into JSON.
func (i *Image) MarshalJSON() ([]byte, error) {
	computeImData, err := json.Marshal(i.Image)
	if err != nil {
		return nil, err
	}
	computeIm := make(map[string]interface{})
	if err := json.Unmarshal(computeImData, &computeIm); err != nil {
		return nil, err
	}
	computeIm["Project"] = i.Project
	return json.Marshal(computeIm)
}

// Build stores configuration data associated with the image build session.
type Build struct {
	GCSBucket      string
	GCSDir         string
	Project        string
	Zone           string
	MachineType    string
	ServiceAccount string
	DiskType       string
	DiskSize       int
	GPUType        string
	Timeout        string
	GCSFiles       []string
	GCEEndpoint    string
	Network        string
	Subnet         string
}

// SaveConfigToFile clears the target config file and then saves the new config
// data.
func SaveConfigToFile(configFile *os.File, v interface{}) error {
	if _, err := configFile.Seek(0, 0); err != nil {
		return fmt.Errorf("cannot seek config file, error msg:(%v)", err)
	}
	if err := configFile.Truncate(0); err != nil {
		return fmt.Errorf("cannot truncate config file, error msg:(%v)", err)
	}
	if err := Save(configFile, v); err != nil {
		return fmt.Errorf("cannot save config file, error msg:(%v)", err)
	}
	return nil
}

// SaveConfigToPath does the same thing as SaveConfigToFile, but updates a file
// system path.
func SaveConfigToPath(configPath string, config interface{}) (err error) {
	configFile, err := os.OpenFile(configPath, os.O_RDWR, 0666)
	if err != nil {
		return err
	}
	defer utils.CheckClose(configFile, "error writing to "+configPath, &err)
	return SaveConfigToFile(configFile, config)
}

// Save serializes the given struct as JSON and writes it out.
func Save(w io.Writer, v interface{}) error {
	data, err := json.Marshal(v)
	if err != nil {
		return err
	}
	_, err = io.WriteString(w, string(data))
	return err
}

// Load deserializes JSON formatted data into the given struct.
func Load(r io.Reader, v interface{}) error {
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return err
	}
	return json.Unmarshal(data, v)
}

// LoadFromFile loads JSON data from a file into the given struct.
func LoadFromFile(path string, v interface{}) (err error) {
	r, err := os.Open(path)
	if err != nil {
		return err
	}
	defer utils.CheckClose(r, fmt.Sprintf("error closing %q", path), &err)
	return Load(r, v)
}
