/*
 * @description: 访问权限认证
 * @Author: CP
 * @Date: 2020-10-09 10:43:39
 * @FilePath: \construction_management\web\middleware\accessAuth.go
 */
package middleware

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"

	"github.com/kataras/iris/v12"
	"go.mod/dao"
	"go.mod/datasource"
	"go.mod/models"
	"go.mod/web/utils"
)

// 员工表权限解析
type permission struct {
	Add    int ` json:"add" `
	Delete int ` json:"delete" `
	Access int ` json:"access" `
}

// 权限JSON对象
type permissionPath struct {
	Contract       path     `json:"contract" `
	Safe           path     `json:"safe" `
	Quality        path     `json:"quality" `
	ProjectSetting []string `json:"projectSetting" `
}

// 对象中地址列表
type path struct {
	Add    []string `json:"add" `
	Access []string `json:"access" `
	Delete []string `json:"delete" `
}

// 权限验证中间件
func AccessAuth(ctx iris.Context) {

	// 1.获得成员信息
	account := ctx.Values().Get("account").(*models.CmProjectAccount)
	if account.Enable == 0 {
		ctx.JSON(iris.Map{"code": 2, "msg": "该账号被禁用"})
		return
	}

	// 需要先设置标段ID，在获得权限进行判断
	// 账号活动状态下，入口必须是 /api/contract/survey，
	path := ctx.Path()
	if path == "/api/contract/survey" || path == "/api/quality/survey" || path == "/api/safe/survey" {
		ctx.Next()
		return
	}

	// 1-1获得标段ID --没有标段ID 默认为0
	bidsectionIdHeader := ctx.GetHeader("bidsectionId")
	bidsectionId, _ := utils.GetDecryptId(bidsectionIdHeader)

	// if bidsectionIdHeader == "" {
	// 	ctx.JSON(iris.Map{"code": 2, "msg": "标段解析出错"})
	// 	return
	// } else {
	// 	bidsectionId, err := utils.GetDecryptId(bidsectionIdHeader)
	// 	if err != nil {
	// 		ctx.JSON(iris.Map{"code": 2, "msg": "标段解析出错"})
	// 		return
	// 	}

	// }

	// key := fmt.Sprintf("pm_%d_%d", account.ProjectId, account.Id)
	// bidsectionId := lib.NewRedis().GetBidsectionIdByCache(key)

	// 1-2 获得账号权限
	permissionAccountDao := dao.NewPermissionAccountDao(datasource.InstanceDbMaster())
	permissionData := permissionAccountDao.GetBidsectionIdAccountId(bidsectionId, account.Id)
	// permissionData := s.permissionAccountDao.GetBidsectionId(bidsectionId)
	// fmt.Println(bidsectionId, account.Id)
	// fmt.Println(permissionData)

	// 1-1.是管理员- 拥有所有权限
	if account.IsAdmin != 1 {
		// if account.IsAdmin == 1 {
		// 2.获得员工可访问的权限
		contractPermission := permission{}
		if permissionData.ContractPermission != "" {
			err := json.Unmarshal([]byte(permissionData.ContractPermission), &contractPermission)
			// 错误后 全部权限默认为0
			if err != nil {
				log.Println("合同权限解析错误:err=", err)
			}
		}
		safePermission := permission{}
		if permissionData.SafePermission != "" {
			err := json.Unmarshal([]byte(permissionData.SafePermission), &safePermission)
			if err != nil {
				log.Println("安全权限解析错误:err=", err)
			}
		}
		qualityPermission := permission{}
		if permissionData.QualityPermission != "" {
			err := json.Unmarshal([]byte(permissionData.QualityPermission), &qualityPermission)
			if err != nil {
				log.Println("质量权限解析错误:err=", err)
			}
		}

		// 2-1获得权限列表
		permissionPath := permissionPath{}
		permissionPathData, err := ioutil.ReadFile("../lib/permission.json")
		err = json.Unmarshal(permissionPathData, &permissionPath)
		if err != nil {
			log.Println("权限解析错误:err=", err)
			ctx.JSON(iris.Map{"code": 2, "msg": "权限解析错误"})
			return
		}
		// 2-2 不容许访问的权限--比对访问路径
		requestPath := ctx.Path()

		// 2-3 请求的类型
		method := ctx.Request().Method

		// 合同权限
		err = verifyAuth(contractPermission, permissionPath.Contract, requestPath, method)
		if err != nil {
			ctx.JSON(iris.Map{"code": 2, "msg": fmt.Sprintf("%s", err)})
			return
		}
		// 安全权限
		err = verifyAuth(safePermission, permissionPath.Safe, requestPath, method)
		if err != nil {
			ctx.JSON(iris.Map{"code": 2, "msg": fmt.Sprintf("%s", err)})
			return
		}
		// 质量权限
		err = verifyAuth(qualityPermission, permissionPath.Quality, requestPath, method)
		if err != nil {
			ctx.JSON(iris.Map{"code": 2, "msg": fmt.Sprintf("%s", err)})
			return
		}
		// 项目设置 -只有管理员才能访问
		for _, path := range permissionPath.ProjectSetting {
			if path == requestPath {
				ctx.JSON(iris.Map{"code": 2, "msg": "无权访问"})
				return
			}
		}

	}

	ctx.Next()
}

// 验证权限路径
func verifyAuth(permission permission, pathList path, requestPath string, method string) error {
	if permission.Add == 0 {
		for _, path := range pathList.Add {
			if path == requestPath && method == "POST" {
				return errors.New("无权访问")
			}
		}
	}
	if permission.Access == 0 {
		for _, path := range pathList.Access {
			if path == requestPath && method == "GET" {
				return errors.New("无权访问")
			}
		}
	}
	if permission.Delete == 0 {
		for _, path := range pathList.Delete {
			if path == requestPath && (method == "POST" || method == "DELETE") {
				return errors.New("无权访问")
			}
		}
	}
	return nil
}
