/*
 Copyright 2017 the original author or authors.

 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 impl

import (
	"fmt"
	"log"
	"os"

	"gerrit.opencord.org/abstract-olt/internal/pkg/settings"
	"gerrit.opencord.org/abstract-olt/models"
	"github.com/mongodb/mongo-go-driver/bson"
	"github.com/mongodb/mongo-go-driver/mongo"
	"github.com/mongodb/mongo-go-driver/mongo/options"
	context "golang.org/x/net/context"
)

/*
DoOutput - creates a backup and stores it to disk/mongodb
*/
func DoOutput() (bool, error) {
	if isDirty {
		myChan := getSyncChannel()
		<-myChan
		defer done(myChan, true)
		chassisMap := models.GetChassisMap()
		if settings.GetMongo() {
			clientOptions := options.Client()
			creds := options.Credential{AuthMechanism: "SCRAM-SHA-256", AuthSource: "AbstractOLT", Username: settings.GetMongoUser(), Password: settings.GetMongoPassword()}
			clientOptions.SetAuth(creds)

			client, err := mongo.NewClientWithOptions(settings.GetMongodb(), clientOptions)
			client.Connect(context.Background())
			if err != nil {
				log.Printf("client connect to mongo db @%s failed with %v\n", settings.GetMongodb(), err)
			}
			defer client.Disconnect(context.Background())
			for clli, chassisHolder := range *chassisMap {
				json, _ := (chassisHolder).Serialize()
				collection := client.Database("AbstractOLT").Collection("backups")
				//update or insert if not existent
				upsert := true
				res, err := collection.UpdateOne(context.Background(),
					bson.D{
						{"_id", clli},
					},
					bson.D{
						{
							"$set", bson.D{
								{"body", json},
							},
						},
					}, &options.UpdateOptions{Upsert: &upsert})

				if err != nil {
					log.Printf("collection.UpdateOne failed with %v\n", err)
				} else {
					id := res.UpsertedID
					if settings.GetDebug() {
						log.Printf("Update Succeeded with id %v\n", id)
					}
				}
			}
		} else {
			for clli, chassisHolder := range *chassisMap {

				json, _ := (chassisHolder).Serialize()
				if settings.GetMongo() {

				} else {
					//TODO parameterize dump location
					backupFile := fmt.Sprintf("backup/%s", clli)
					f, _ := os.Create(backupFile)

					defer f.Close()

					_, _ = f.WriteString(string(json))
					f.Sync()
				}
			}
		}
		isDirty = false
	} else {
		if settings.GetDebug() {
			log.Print("Not dirty not dumping config")
		}

	}
	return true, nil

}
