package handlers import ( "fmt" "net/http" "strconv" "github.com/go-chi/chi/v5" "omixlab.com/mosis-portal/internal/database" "omixlab.com/mosis-portal/internal/storage" ) // StoreHandler handles public store endpoints type StoreHandler struct { db *database.DB storage *storage.Storage } // NewStoreHandler creates a new store handler func NewStoreHandler(db *database.DB, store *storage.Storage) *StoreHandler { return &StoreHandler{db: db, storage: store} } // ListApps returns published apps for the store func (h *StoreHandler) ListApps(w http.ResponseWriter, r *http.Request) { // Parse query parameters query := r.URL.Query().Get("q") category := r.URL.Query().Get("category") sort := r.URL.Query().Get("sort") page, _ := strconv.Atoi(r.URL.Query().Get("page")) limit, _ := strconv.Atoi(r.URL.Query().Get("limit")) if page < 1 { page = 1 } if limit < 1 || limit > 100 { limit = 20 } apps, total, err := h.db.ListPublishedApps(r.Context(), query, category, sort, page, limit) if err != nil { Error(w, "failed to list apps: "+err.Error(), http.StatusInternalServerError) return } JSON(w, http.StatusOK, map[string]interface{}{ "apps": apps, "total": total, "pagination": map[string]interface{}{ "page": page, "limit": limit, "total": total, "total_pages": (total + limit - 1) / limit, }, }) } // GetApp returns a published app by package ID func (h *StoreHandler) GetApp(w http.ResponseWriter, r *http.Request) { packageID := chi.URLParam(r, "packageID") app, err := h.db.GetPublishedApp(r.Context(), packageID) if err != nil { Error(w, "app not found", http.StatusNotFound) return } JSON(w, http.StatusOK, app) } // Download returns download info for the latest version of an app func (h *StoreHandler) Download(w http.ResponseWriter, r *http.Request) { packageID := chi.URLParam(r, "packageID") // Get app to find developer ID app, err := h.db.GetAppByPackageID(r.Context(), packageID) if err != nil { Error(w, "app not found", http.StatusNotFound) return } version, err := h.db.GetLatestPublishedVersion(r.Context(), packageID) if err != nil { Error(w, "no published version found", http.StatusNotFound) return } // Build download URL downloadURL := fmt.Sprintf("/downloads/%s/%s/%d/package.mosis", app.DeveloperID, app.ID, version.VersionCode) JSON(w, http.StatusOK, map[string]interface{}{ "download_url": downloadURL, "version": version.VersionName, "version_code": version.VersionCode, "size": version.PackageSize, "signature": version.Signature, }) } // DownloadVersion returns download info for a specific version func (h *StoreHandler) DownloadVersion(w http.ResponseWriter, r *http.Request) { packageID := chi.URLParam(r, "packageID") versionCodeStr := chi.URLParam(r, "versionCode") versionCode, err := strconv.Atoi(versionCodeStr) if err != nil { Error(w, "invalid version code", http.StatusBadRequest) return } // Get app to find developer ID app, err := h.db.GetAppByPackageID(r.Context(), packageID) if err != nil { Error(w, "app not found", http.StatusNotFound) return } version, err := h.db.GetPublishedVersionByCode(r.Context(), packageID, versionCode) if err != nil { Error(w, "version not found", http.StatusNotFound) return } // Build download URL downloadURL := fmt.Sprintf("/downloads/%s/%s/%d/package.mosis", app.DeveloperID, app.ID, version.VersionCode) JSON(w, http.StatusOK, map[string]interface{}{ "download_url": downloadURL, "version": version.VersionName, "version_code": version.VersionCode, "size": version.PackageSize, "signature": version.Signature, }) } // CheckUpdates checks for app updates func (h *StoreHandler) CheckUpdates(w http.ResponseWriter, r *http.Request) { // Parse request body for installed apps // For now, return empty updates JSON(w, http.StatusOK, map[string]interface{}{ "updates": []interface{}{}, }) }