/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 data

import (
	"path/filepath"
	"time"

	"github.com/apache/answer/pkg/dir"
	"github.com/apache/answer/plugin"
	_ "github.com/go-sql-driver/mysql"
	_ "github.com/lib/pq"
	"github.com/segmentfault/pacman/cache"
	"github.com/segmentfault/pacman/contrib/cache/memory"
	"github.com/segmentfault/pacman/log"
	_ "modernc.org/sqlite"
	"xorm.io/xorm"
	ormlog "xorm.io/xorm/log"
	"xorm.io/xorm/names"
	"xorm.io/xorm/schemas"
)

// Data data
type Data struct {
	DB    *xorm.Engine
	Cache cache.Cache
}

// NewData new data instance
func NewData(db *xorm.Engine, cache cache.Cache) (*Data, func(), error) {
	cleanup := func() {
		log.Info("closing the data resources")
		_ = db.Close()
	}
	return &Data{DB: db, Cache: cache}, cleanup, nil
}

// NewDB new database instance
func NewDB(debug bool, dataConf *Database) (*xorm.Engine, error) {
	if dataConf.Driver == "" {
		dataConf.Driver = string(schemas.MYSQL)
	}
	if dataConf.Driver == string(schemas.SQLITE) {
		dataConf.Driver = "sqlite"
		dbFileDir := filepath.Dir(dataConf.Connection)
		log.Debugf("try to create database directory %s", dbFileDir)
		if err := dir.CreateDirIfNotExist(dbFileDir); err != nil {
			log.Errorf("create database dir failed: %s", err)
		}
		dataConf.MaxOpenConn = 1
	}
	engine, err := xorm.NewEngine(dataConf.Driver, dataConf.Connection)
	if err != nil {
		return nil, err
	}

	if debug {
		engine.ShowSQL(true)
	} else {
		engine.SetLogLevel(ormlog.LOG_ERR)
	}

	if err = engine.Ping(); err != nil {
		return nil, err
	}

	if dataConf.MaxIdleConn > 0 {
		engine.SetMaxIdleConns(dataConf.MaxIdleConn)
	}
	if dataConf.MaxOpenConn > 0 {
		engine.SetMaxOpenConns(dataConf.MaxOpenConn)
	}
	if dataConf.ConnMaxLifeTime > 0 {
		engine.SetConnMaxLifetime(time.Duration(dataConf.ConnMaxLifeTime) * time.Second)
	}
	engine.SetColumnMapper(names.GonicMapper{})
	return engine, nil
}

// NewCache new cache instance
func NewCache(c *CacheConf) (cache.Cache, func(), error) {
	var pluginCache plugin.Cache
	_ = plugin.CallCache(func(fn plugin.Cache) error {
		pluginCache = fn
		return nil
	})
	if pluginCache != nil {
		return pluginCache, func() {}, nil
	}

	// TODO What cache type should be initialized according to the configuration file
	memCache := memory.NewCache()

	if len(c.FilePath) > 0 {
		cacheFileDir := filepath.Dir(c.FilePath)
		log.Debugf("try to create cache directory %s", cacheFileDir)
		err := dir.CreateDirIfNotExist(cacheFileDir)
		if err != nil {
			log.Errorf("create cache dir failed: %s", err)
		}
		log.Infof("try to load cache file from %s", c.FilePath)
		if err := memory.Load(memCache, c.FilePath); err != nil {
			log.Warn(err)
		}
		go func() {
			ticker := time.Tick(time.Minute)
			for range ticker {
				if err := memory.Save(memCache, c.FilePath); err != nil {
					log.Warn(err)
				}
			}
		}()
	}
	cleanup := func() {
		log.Infof("try to save cache file to %s", c.FilePath)
		if err := memory.Save(memCache, c.FilePath); err != nil {
			log.Warn(err)
		}
	}
	return memCache, cleanup, nil
}
