package ogloszenia.rest;

import java.math.BigDecimal;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import ogloszenia.baza.DostepDoBazy;
import ogloszenia.baza.OgloszeniaDAO;
import ogloszenia.exn.BladBazyDanych;
import ogloszenia.exn.NieznanyRekord;
import ogloszenia.model.ListaOgloszen;
import ogloszenia.model.Samochodowe;
import ogloszenia.util.FotoUtil;

@Path("/ogloszenia")
public class ROgloszenia {

	@GET
	@Produces({"application/json", "application/xml", "text/plain"})
	public ListaOgloszen odczytajWszystkie() throws BladBazyDanych {
		try(DostepDoBazy db = new DostepDoBazy()) {
			OgloszeniaDAO dao = db.ogloszeniaDAO();
			return new ListaOgloszen(dao.odczytajWszystkie());
		}
	}
	
	@GET
	@Path("/{id}")
	@Produces({"application/json", "application/xml", "text/plain"})
	public Samochodowe odczytajJedno(
			@PathParam("id") int idOgloszenia) throws BladBazyDanych, NieznanyRekord {
		try(DostepDoBazy db = new DostepDoBazy()) {
			OgloszeniaDAO dao = db.ogloszeniaDAO();
			return dao.odczytajWgId(idOgloszenia);
		}
	}
	
	@GET
	@Path("/{id}/cena")
	@Produces({"text/plain", "application/json"})
	public BigDecimal getCena(
			@PathParam("id") int idOgloszenia) throws BladBazyDanych, NieznanyRekord {
		try(DostepDoBazy db = new DostepDoBazy()) {
			OgloszeniaDAO dao = db.ogloszeniaDAO();
			return dao.odczytajWgId(idOgloszenia).getCena();
		}
	}
	
	// HTTP PUT służy do zapisania przesłanych danych pod podanym adresem.
	@PUT
	@Path("/{id}/cena")
	@Consumes({"text/plain", "application/json"})
	public void setCena(BigDecimal nowaCena,
			@PathParam("id") int idOgloszenia) throws BladBazyDanych, NieznanyRekord {
		// Metoda restowa może posiadać najwyżej jeden parametr nieoznaczony żadną adnotacją.
		// Do tego parametru jest wpisywana wartość, która została przysłana jako treść żadania (content / body / entity) 
		try(DostepDoBazy db = new DostepDoBazy()) {
			OgloszeniaDAO dao = db.ogloszeniaDAO();
			Samochodowe ogloszenie = dao.odczytajWgId(idOgloszenia);
			ogloszenie.setCena(nowaCena);
			dao.aktualizuj(ogloszenie);
		}
	}
	
	@GET
	@Path("/{id}/foto")
	@Produces("image/jpeg")
	public byte[] getFoto(
			@PathParam("id") int idOgloszenia) throws NieznanyRekord {
		return FotoUtil.wczytajFoto(idOgloszenia);
	}
	
	// HTTP POST służy do przesłania danych od klienta na serwer.
	// A co serwer z tym zrobi, tego standard nie specyfikuje...
	// W praktyce POST w usługach REST-owych najczęściej używa się do zapisywania nowych rekordów, gdy nie wiadomo z góry pod jakim adresem zostaną zapisane.
	// Wygląda to jak przysyłanie nowych rekordów do katalogu (jak add w Javie / append w Pythonie)
	
	// W tym konkretnym przypadku metoda umożlwia też aktualizację istniejących rekordów (jeśli mają podane ID),
	// ale w praktyce usług REST-owych chodzi głównie o dodawanie nowych rekordów.
	@POST
	@Consumes({"application/json", "application/xml"})
	@Produces({"application/json", "application/xml"})
	public Samochodowe zapiszOgloszenie(Samochodowe ogloszenie) throws BladBazyDanych {
		try(DostepDoBazy db = new DostepDoBazy()) {
			OgloszeniaDAO dao = db.ogloszeniaDAO();
			dao.zapisz(ogloszenie);
			return ogloszenie;
			// W tej wersji usługi POST odsyła "uzupełniony" obiekt ogłoszenia, dzięki temu klient dowie się co i gdzie zapisał.
		}
	}
	
	@DELETE
	@Path("/{id}")
	public void usunOgloszenie(@PathParam("id") int idOgloszenia) throws BladBazyDanych {
		try(DostepDoBazy db = new DostepDoBazy()) {
			OgloszeniaDAO dao = db.ogloszeniaDAO();
			dao.usun(idOgloszenia);
		}
	}
	
}
