package sklep.rest;

import java.math.BigDecimal;
import java.util.List;

import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import sklep.db.DBConnection;
import sklep.db.DBException;
import sklep.db.ProductDAO;
import sklep.db.RecordNotFound;
import sklep.model.Product;

/* JAX-RS - część Javy EE
 * Aplikacja (projekt) składa się z wielu "resource classes", z których każda obsługuje pewien rodzaj encji
 * np. pod adresem /products działa ta klasa RProduct, która zajmuje się obsługą produktów
 * a pod adresem /orders działa ROrder, która zajmuje się zamówieniami.
 * Przykładowa dobra (szczegółowa) dokumentacja: https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest3x/index.html
 *  
 *  W usługach REST struktura adresów URL odpowiada logicznej strukturze danych.
 * Typowe jest, że * pod adresem "katalogu", np. /products , dostępna jest lista wszystkich rekordów
 * (lub ogólne informacje, lub jakiś sposób przeglądania - gdyby było ich za dużo do zwrócenia na raz)
 * a idąc dalej wgłąb ścieżki przechodzimy do "pojedynczych rekordów", np. /products/2
 * 
 * W tej klasie wejdziemy nawet do wnętrza produktów i udostępnimy osobno cenę
 * /products/2/price
 * W praktyce nie robi się tego zbyt często, ale tu zobaczymy jako przykład możliwości.
 * 
 * To od programisty (twórcy usługi) zależy jakie adresy i jakie operacje pod tymi adresami udostępnia.
 * 
 * Ta klasa udostępnia (i przyjmuje) dane produktów w różnych formatach.
 * Gdy w Produces jest wiele formatów, to klient może wybrać za pomocą nagłówka Accept
 * Gdy w Consumes jest wiele formatów, to klient może przysłać dane w dowolnym z nich (nagłówek Content-Type)
 */


@Path("/products")
public class RProducts {
    
    @GET
    @Produces("application/json")
    public List<Product> readAll() throws DBException {
        try(DBConnection db = DBConnection.open()) {
            ProductDAO productDAO = db.productDAO();
            return productDAO.readAll();
        }
    }
    
    @GET
    @Produces("application/json")
    @Path("/{id}")
    public Product readOne(@PathParam("id") int productId) throws DBException, RecordNotFound {
        try(DBConnection db = DBConnection.open()) {
            ProductDAO productDAO = db.productDAO();
            return productDAO.findById(productId);
        }
    }
    
    // Dostęp do pojedynczego pola w rekordzie - nie ma obowiązku implementowania takich metod
    // i nie robi robi się tego zbyt często, ale pokazujemy, że można (gdyby klient często potrzebował dostępu do wybranego szczegółu)
    @GET
    @Produces("application/json")
    @Path("/{id}/price")
    public BigDecimal getPrice(@PathParam("id") int productId) throws DBException, RecordNotFound {
        try(DBConnection db = DBConnection.open()) {
            ProductDAO productDAO = db.productDAO();
            Product product = productDAO.findById(productId);
            return product.getPrice();
        }
    }
    
    // Operacja HTTP PUT zapisuje zasób pod podanym adresem.
    // W zapytaniach typu PUT i POST klient wysyła dane na serwer (treść zapytania: "body" / "entity" / "content" ...)
    // W JAX-RS metoda może posiadać tylko jeden parametr bez adnotacji i to właśnie przez ten parametr przekazywana jest treść zapytania
    // (te dane, które przysłał klient). Format tych danych opisuje adnotacja @Consumes
    @PUT
    @Consumes("application/json")
    @Path("/{id}/price")
    public void putPrice(@PathParam("id") int productId,
            BigDecimal newPrice) throws DBException, RecordNotFound {
        try(DBConnection db = DBConnection.open()) {
            ProductDAO productDAO = db.productDAO();
            Product product = productDAO.findById(productId);
            product.setPrice(newPrice);
            productDAO.update(product);
            db.commit();
        }
    }    

    @GET
    @Produces("image/jpeg")
    @Path("/{id}/photo")
    // http://localhost:8080/PC32-RestSerwer/products/1/photo
    public byte[] photo(@PathParam("id") int productId) throws DBException, RecordNotFound {
        return PhotoUtil.readBytes(productId);
    }
    
}
