/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
*
* This file is part of Dnote.
*
* Dnote is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dnote is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Dnote. If not, see .
*/
package api
// import (
// "fmt"
// "net/http"
// "net/url"
// "strconv"
// "strings"
// "time"
//
// "github.com/dnote/dnote/pkg/server/database"
// "github.com/dnote/dnote/pkg/server/helpers"
// "github.com/dnote/dnote/pkg/server/middleware"
// "github.com/dnote/dnote/pkg/server/operations"
// "github.com/dnote/dnote/pkg/server/presenters"
// "github.com/gorilla/mux"
// "github.com/jinzhu/gorm"
// "github.com/pkg/errors"
// )
//
// type ftsParams struct {
// HighlightAll bool
// }
//
// func getHeadlineOptions(params *ftsParams) string {
// headlineOptions := []string{
// "StartSel=",
// "StopSel=",
// "ShortWord=0",
// }
//
// if params != nil && params.HighlightAll {
// headlineOptions = append(headlineOptions, "HighlightAll=true")
// } else {
// headlineOptions = append(headlineOptions, "MaxFragments=3, MaxWords=50, MinWords=10")
// }
//
// return strings.Join(headlineOptions, ",")
// }
//
// func selectFTSFields(conn *gorm.DB, search string, params *ftsParams) *gorm.DB {
// headlineOpts := getHeadlineOptions(params)
//
// return conn.Select(`
// notes.id,
// notes.uuid,
// notes.created_at,
// notes.updated_at,
// notes.book_uuid,
// notes.user_id,
// notes.added_on,
// notes.edited_on,
// notes.usn,
// notes.deleted,
// notes.encrypted,
// ts_headline('english_nostop', notes.body, plainto_tsquery('english_nostop', ?), ?) AS body
// `, search, headlineOpts)
// }
//
// func respondWithNote(w http.ResponseWriter, note database.Note) {
// presentedNote := presenters.PresentNote(note)
//
// middleware.RespondJSON(w, http.StatusOK, presentedNote)
// }
//
// func parseSearchQuery(q url.Values) string {
// searchStr := q.Get("q")
//
// return escapeSearchQuery(searchStr)
// }
//
// func getNoteBaseQuery(db *gorm.DB, noteUUID string, search string) *gorm.DB {
// var conn *gorm.DB
// if search != "" {
// conn = selectFTSFields(db, search, &ftsParams{HighlightAll: true})
// } else {
// conn = db
// }
//
// conn = conn.Where("notes.uuid = ? AND deleted = ?", noteUUID, false)
//
// return conn
// }
//
// func (a *API) getNote(w http.ResponseWriter, r *http.Request) {
// user, _, err := middleware.AuthWithSession(a.App.DB, r)
// if err != nil {
// middleware.DoError(w, "authenticating", err, http.StatusInternalServerError)
// return
// }
//
// vars := mux.Vars(r)
// noteUUID := vars["noteUUID"]
//
// note, ok, err := operations.GetNote(a.App.DB, noteUUID, &user)
// if !ok {
// middleware.RespondNotFound(w)
// return
// }
// if err != nil {
// middleware.DoError(w, "finding note", err, http.StatusInternalServerError)
// return
// }
//
// respondWithNote(w, note)
// }
//
// /**** getNotesHandler */
//
// // GetNotesResponse is a reponse by getNotesHandler
// type GetNotesResponse struct {
// Notes []presenters.Note `json:"notes"`
// Total int `json:"total"`
// }
//
// type dateRange struct {
// lower int64
// upper int64
// }
//
// func (a *API) getNotes(w http.ResponseWriter, r *http.Request) {
// user, ok := r.Context().Value(helpers.KeyUser).(database.User)
// if !ok {
// middleware.DoError(w, "No authenticated user found", nil, http.StatusInternalServerError)
// return
// }
// query := r.URL.Query()
//
// respondGetNotes(a.App.DB, user.ID, query, w)
// }
//
// func respondGetNotes(db *gorm.DB, userID int, query url.Values, w http.ResponseWriter) {
// q, err := parseGetNotesQuery(query)
// if err != nil {
// http.Error(w, err.Error(), http.StatusBadRequest)
// return
// }
//
// conn := getNotesBaseQuery(db, userID, q)
//
// var total int
// if err := conn.Model(database.Note{}).Count(&total).Error; err != nil {
// middleware.DoError(w, "counting total", err, http.StatusInternalServerError)
// return
// }
//
// notes := []database.Note{}
// if total != 0 {
// conn = orderGetNotes(conn)
// conn = database.PreloadNote(conn)
// conn = paginate(conn, q.Page)
//
// if err := conn.Find(¬es).Error; err != nil {
// middleware.DoError(w, "finding notes", err, http.StatusInternalServerError)
// return
// }
// }
//
// response := GetNotesResponse{
// Notes: presenters.PresentNotes(notes),
// Total: total,
// }
// middleware.RespondJSON(w, http.StatusOK, response)
// }
//
// type getNotesQuery struct {
// Year int
// Month int
// Page int
// Books []string
// Search string
// Encrypted bool
// }
//
// func parseGetNotesQuery(q url.Values) (getNotesQuery, error) {
// yearStr := q.Get("year")
// monthStr := q.Get("month")
// books := q["book"]
// pageStr := q.Get("page")
// encryptedStr := q.Get("encrypted")
//
// fmt.Println("books", books)
//
// var page int
// if len(pageStr) > 0 {
// p, err := strconv.Atoi(pageStr)
// if err != nil {
// return getNotesQuery{}, errors.Errorf("invalid page %s", pageStr)
// }
// if p < 1 {
// return getNotesQuery{}, errors.Errorf("invalid page %s", pageStr)
// }
//
// page = p
// } else {
// page = 1
// }
//
// var year int
// if len(yearStr) > 0 {
// y, err := strconv.Atoi(yearStr)
// if err != nil {
// return getNotesQuery{}, errors.Errorf("invalid year %s", yearStr)
// }
//
// year = y
// }
//
// var month int
// if len(monthStr) > 0 {
// m, err := strconv.Atoi(monthStr)
// if err != nil {
// return getNotesQuery{}, errors.Errorf("invalid month %s", monthStr)
// }
// if m < 1 || m > 12 {
// return getNotesQuery{}, errors.Errorf("invalid month %s", monthStr)
// }
//
// month = m
// }
//
// var encrypted bool
// if strings.ToLower(encryptedStr) == "true" {
// encrypted = true
// } else {
// encrypted = false
// }
//
// ret := getNotesQuery{
// Year: year,
// Month: month,
// Page: page,
// Search: parseSearchQuery(q),
// Books: books,
// Encrypted: encrypted,
// }
//
// return ret, nil
// }
//
// func getDateBounds(year, month int) (int64, int64) {
// var yearUpperbound, monthUpperbound int
//
// if month == 12 {
// monthUpperbound = 1
// yearUpperbound = year + 1
// } else {
// monthUpperbound = month + 1
// yearUpperbound = year
// }
//
// lower := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.UTC).UnixNano()
// upper := time.Date(yearUpperbound, time.Month(monthUpperbound), 1, 0, 0, 0, 0, time.UTC).UnixNano()
//
// return lower, upper
// }
//
// func getNotesBaseQuery(db *gorm.DB, userID int, q getNotesQuery) *gorm.DB {
// conn := db.Where(
// "notes.user_id = ? AND notes.deleted = ? AND notes.encrypted = ?",
// userID, false, q.Encrypted,
// )
//
// if q.Search != "" {
// conn = selectFTSFields(conn, q.Search, nil)
// conn = conn.Where("tsv @@ plainto_tsquery('english_nostop', ?)", q.Search)
// }
//
// if len(q.Books) > 0 {
// conn = conn.Joins("INNER JOIN books ON books.uuid = notes.book_uuid").
// Where("books.label in (?)", q.Books)
// }
//
// if q.Year != 0 || q.Month != 0 {
// dateLowerbound, dateUpperbound := getDateBounds(q.Year, q.Month)
// conn = conn.Where("notes.added_on >= ? AND notes.added_on < ?", dateLowerbound, dateUpperbound)
// }
//
// return conn
// }
//
// func orderGetNotes(conn *gorm.DB) *gorm.DB {
// return conn.Order("notes.updated_at DESC, notes.id DESC")
// }
//
// // escapeSearchQuery escapes the query for full text search
// func escapeSearchQuery(searchQuery string) string {
// return strings.Join(strings.Fields(searchQuery), "&")
// }
//
// func (a *API) legacyGetNotes(w http.ResponseWriter, r *http.Request) {
// user, ok := r.Context().Value(helpers.KeyUser).(database.User)
// if !ok {
// middleware.DoError(w, "No authenticated user found", nil, http.StatusInternalServerError)
// return
// }
//
// var notes []database.Note
// if err := a.App.DB.Where("user_id = ? AND encrypted = true", user.ID).Find(¬es).Error; err != nil {
// middleware.DoError(w, "finding notes", err, http.StatusInternalServerError)
// return
// }
//
// presented := presenters.PresentNotes(notes)
// middleware.RespondJSON(w, http.StatusOK, presented)
// }