// 升级为Api, beta.4
func (this *UpgradeService) Api(userId string) (ok bool, msg string) {
	if configService.GetGlobalStringConfig("UpgradeBetaToBeta4") != "" {
		return false, "Leanote have been upgraded"
	}

	// user
	db.UpdateByQField(db.Users, bson.M{}, "Usn", 200000)

	// notebook
	db.UpdateByQField(db.Notebooks, bson.M{}, "IsDeleted", false)
	this.setNotebookUsn()

	// note
	// 1-N
	db.UpdateByQField(db.Notes, bson.M{}, "IsDeleted", false)
	this.setNoteUsn()

	// tag
	// 1-N
	/// tag, 要重新插入, 将之前的Tag表迁移到NoteTag中
	this.moveTag()

	configService.UpdateGlobalStringConfig(userId, "UpgradeBetaToBeta4", "1")

	return true, ""
}
// 使用主题
func (this *ThemeService) ActiveTheme(userId, themeId string) (ok bool) {
	if db.Has(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId), "UserId": bson.ObjectIdHex(userId)}) {
		// 之前的设为false
		db.UpdateByQField(db.Themes, bson.M{"UserId": bson.ObjectIdHex(userId), "IsActive": true}, "IsActive", false)
		// 现在的设为true
		db.UpdateByQField(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId)}, "IsActive", true)

		// UserBlog ThemeId
		db.UpdateByQField(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, "ThemeId", bson.ObjectIdHex(themeId))
		return true
	}
	return false
}
// 重新统计笔记本下的笔记数目
// noteSevice: AddNote, CopyNote, CopySharedNote, MoveNote
// trashService: DeleteNote (recove不用, 都统一在MoveNote里了)
func (this *NotebookService) ReCountNotebookNumberNotes(notebookId string) bool {
	notebookIdO := bson.ObjectIdHex(notebookId)
	count := db.Count(db.Notes, bson.M{"NotebookId": notebookIdO, "IsTrash": false, "IsDeleted": false})
	Log(count)
	Log(notebookId)
	return db.UpdateByQField(db.Notebooks, bson.M{"_id": notebookIdO}, "NumberNotes", count)
}
func (this *ShareService) UpdateShareNotebookPerm(notebookId string, perm int, userId, toUserId string) bool {
	return db.UpdateByQField(db.ShareNotebooks,
		bson.M{"NotebookId": bson.ObjectIdHex(notebookId), "UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(toUserId)},
		"Perm",
		perm,
	)
}
// 公开主题, 只有管理员才有权限, 之前没公开的变成公开
func (this *ThemeService) PublicTheme(userId, themeId string) (ok bool) {
	// 是否是管理员?
	userInfo := userService.GetUserInfo(userId)
	if userInfo.Username == configService.GetAdminUsername() {
		theme := this.GetThemeById(themeId)
		return db.UpdateByQField(db.Themes, bson.M{"UserId": bson.ObjectIdHex(userId), "_id": bson.ObjectIdHex(themeId)}, "IsDefault", !theme.IsDefault)
	}
	return false
}
func (this *UpgradeService) setNoteUsn() {
	usnI := 1
	notes := []info.Note{}
	db.ListByQWithFields(db.Notes, bson.M{}, []string{"UserId"}, &notes)

	for _, note := range notes {
		db.UpdateByQField(db.Notes, bson.M{"_id": note.NoteId}, "Usn", usnI)
		usnI++
	}
}
// 自增Usn
// 每次notebook,note添加, 修改, 删除, 都要修改
func (this *UserService) IncrUsn(userId string) int {
	user := info.User{}
	query := bson.M{"_id": bson.ObjectIdHex(userId)}
	db.GetByQWithFields(db.Users, query, []string{"Usn"}, &user)
	usn := user.Usn
	usn += 1
	Log("inc Usn")
	db.UpdateByQField(db.Users, query, "Usn", usn)
	return usn
	//	return db.Update(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, bson.M{"$inc": bson.M{"ReadNum": 1}})
}
// 管理员重置密码
func (this *UserService) ResetPwd(adminUserId, userId, pwd string) (ok bool, msg string) {
	if configService.GetAdminUserId() != adminUserId {
		return
	}

	passwd := GenPwd(pwd)
	if passwd == "" {
		return false, "GenerateHash error"
	}
	ok = db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Pwd", passwd)
	return
}
// 更新笔记的附件个数
// addNum 1或-1
func (this *AttachService) updateNoteAttachNum(noteId bson.ObjectId, addNum int) bool {
	num := db.Count(db.Attachs, bson.M{"NoteId": noteId})
	/*
		note := info.Note{}
		note = noteService.GetNoteById(noteId.Hex())
		note.AttachNum += addNum
		if note.AttachNum < 0 {
			note.AttachNum = 0
		}
		Log(note.AttachNum)
	*/
	return db.UpdateByQField(db.Notes, bson.M{"_id": noteId}, "AttachNum", num)
}
//----------------------
// 已经登录了的用户修改密码
func (this *UserService) UpdatePwd(userId, oldPwd, pwd string) (bool, string) {
	userInfo := this.GetUserInfo(userId)
	if !ComparePwd(oldPwd, userInfo.Pwd) {
		return false, "oldPasswordError"
	}

	passwd := GenPwd(pwd)
	if passwd == "" {
		return false, "GenerateHash error"
	}

	ok := db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Pwd", passwd)
	return ok, ""
}
// 修改密码
// 先验证
func (this *PwdService) UpdatePwd(token, pwd string) (bool, string) {
	var tokenInfo info.Token
	var ok bool
	var msg string

	// 先验证
	if ok, msg, tokenInfo = tokenService.VerifyToken(token, info.TokenPwd); !ok {
		return ok, msg
	}
	digest, err := GenerateHash(pwd)
	if err != nil {
		return false, "GenerateHash error"
	}
	passwd := string(digest)
	// 修改密码之
	ok = db.UpdateByQField(db.Users, bson.M{"_id": tokenInfo.UserId}, "Pwd", passwd)

	// 删除token
	tokenService.DeleteToken(tokenInfo.UserId.Hex(), info.TokenPwd)

	return ok, ""
}
// 重新排序
func (this *BlogService) SortSingles(userId string, singleIds []string) (ok bool) {
	if singleIds == nil || len(singleIds) == 0 {
		return
	}
	userBlog := this.GetUserBlog(userId)
	singles := userBlog.Singles
	if singles == nil || len(singles) == 0 {
		return
	}

	singlesMap := map[string]map[string]string{}
	for _, page := range singles {
		singlesMap[page["SingleId"]] = page
	}

	singles2 := make([]map[string]string, len(singles))
	for i, singleId := range singleIds {
		singles2[i] = singlesMap[singleId]
	}

	return db.UpdateByQField(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, "Singles", singles2)
}
func (this *BlogService) updateBlogSingles(userId string, isDelete bool, isAdd bool, singleId, title, urlTitle string) (ok bool) {
	userBlog := this.GetUserBlog(userId)
	singles := userBlog.Singles
	if singles == nil {
		singles = []map[string]string{}
	}
	if isDelete || !isAdd { // 删除或更新, 需要找到相应的
		i := 0
		for _, p := range singles {
			if p["SingleId"] == singleId {
				break
			}
			i++
		}
		// 得到i
		// 找不到
		if i == len(singles) {
		} else {
			// 找到了, 如果是删除, 则删除
			if isDelete {
				singles = append(singles[:i], singles[i+1:]...)
			} else {
				// 是更新
				if title != "" {
					singles[i]["Title"] = title
				}
				if urlTitle != "" {
					singles[i]["UrlTitle"] = urlTitle
				}
			}
		}
	} else {
		// 是添加, 直接添加到最后
		singles = append(singles, map[string]string{"SingleId": singleId, "Title": title, "UrlTitle": urlTitle})
	}
	return db.UpdateByQField(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, "Singles", singles)
}
// 修改主题
func (this *UserService) UpdateTheme(userId, theme string) bool {
	ok := db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Theme", theme)
	return ok
}
// 修改头像
func (this *UserService) UpdateAvatar(userId, avatarPath string) bool {
	userIdO := bson.ObjectIdHex(userId)
	return db.UpdateByQField(db.Users, bson.M{"_id": userIdO}, "Logo", avatarPath)
}
// CateIds
func (this *BlogService) UpateCateIds(userId string, cateIds []string) bool {
	return db.UpdateByQField(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, "CateIds", cateIds)
}