//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.server;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.PrintWriter;
import java.util.Formatter;
import java.util.Locale;

import javax.servlet.ServletResponse;

import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;


/* ------------------------------------------------------------ */
/** Specialized PrintWriter for servlet Responses
 * <p>An instance of ResponseWriter is the {@link PrintWriter} subclass returned by {@link Response#getWriter()}.
 * It differs from the standard {@link PrintWriter} in that:<ul>
 * <li>It does not support autoflush</li>
 * <li>The default Locale for {@link #format(String, Object...)} is the locale obtained by {@link ServletResponse#getLocale()}</li>
 * <li>If a write or print method is called while {@link #checkError()}  returns true, then a {@link RuntimeIOException} is thrown to stop needless iterations.</li>
 * <li>The writer may be reopen to allow for recycling</li>
 * </ul>
 * 
 */
public class ResponseWriter extends PrintWriter
{
    private static final Logger LOG = Log.getLogger(ResponseWriter.class);
    private final static String __lineSeparator = System.getProperty("line.separator");
    private final static String __trueln = "true"+__lineSeparator;
    private final static String __falseln = "false"+__lineSeparator;
    
    private final HttpWriter _httpWriter;
    private final Locale _locale;
    private final String _encoding;
    private IOException _ioException;
    private boolean _isClosed = false;
    private Formatter _formatter;

    public ResponseWriter(HttpWriter httpWriter,Locale locale,String encoding)
    {
        super(httpWriter,false);
        _httpWriter=httpWriter;
        _locale=locale;
        _encoding=encoding;
    }

    public boolean isFor(Locale locale, String encoding)
    {
        if (_locale==null && locale!=null)
            return false;
        if (_encoding==null && encoding!=null)
            return false;
        return _encoding.equalsIgnoreCase(encoding) && _locale.equals(locale);
    }

    protected void reopen()
    {
        synchronized (lock)
        {
            _isClosed=false;
            clearError();
            out=_httpWriter;
        }
    }

    @Override
    protected void clearError()
    {
        synchronized (lock)
        {
            _ioException=null;
            super.clearError();
        }
    }
    
    @Override
    public boolean checkError()
    {
        synchronized (lock)
        {
            return _ioException!=null || super.checkError();
        }
    }
    
    private void setError(Throwable th)
    {
        super.setError();

        if (th instanceof IOException)
            _ioException=(IOException)th;
        else
        {
            _ioException=new IOException(String.valueOf(th));
            _ioException.initCause(th);
        }

        if (LOG.isDebugEnabled())
            LOG.debug(th);
    }


    @Override
    protected void setError()
    {
        setError(new IOException());
    }

    /** Check to make sure that the stream has not been closed */
    private void isOpen() throws IOException
    {       
        if (_ioException!=null)
            throw new RuntimeIOException(_ioException); 
        
        if (_isClosed)
            throw new EofException("Stream closed");
    }

    @Override
    public void flush()
    {
        try
        {
            synchronized (lock)
            {
                isOpen();
                out.flush();
            }
        }
        catch (IOException ex)
        {
            setError(ex);
        }
    }

    @Override
    public void close()
    {
        try
        {
            synchronized (lock)
            {
                out.close();
                _isClosed = true;
            }
        }
        catch (IOException ex)
        {
            setError(ex);
        }
    }

    @Override
    public void write(int c)
    {
        try
        {
            synchronized (lock)
            {
                isOpen();
                out.write(c);
            }
        }
        catch (InterruptedIOException ex)
        {
            LOG.debug(ex);
            Thread.currentThread().interrupt();
        }
        catch (IOException ex)
        {
            setError(ex);
        }
    }
    
    @Override
    public void write(char buf[], int off, int len)
    {
        try
        {
            synchronized (lock)
            {
                isOpen();
                out.write(buf,off,len);
            }
        }
        catch (InterruptedIOException ex)
        {
            LOG.debug(ex);
            Thread.currentThread().interrupt();
        }
        catch (IOException ex)
        {
            setError(ex);
        }
    }

    @Override
    public void write(char buf[])
    { 
        this.write(buf,0,buf.length);
    }

    @Override
    public void write(String s, int off, int len)
    {
        try
        {
            synchronized (lock)
            {
                isOpen();
                out.write(s,off,len);
            }
        }
        catch (InterruptedIOException ex)
        {
            LOG.debug(ex);
            Thread.currentThread().interrupt();
        }
        catch (IOException ex)
        {
            setError(ex);
        }
    }

    @Override
    public void write(String s)
    {
        this.write(s,0,s.length());
    }

    @Override
    public void print(boolean b)
    {
        this.write(b?"true":"false");
    }
    
    @Override
    public void print(char c)
    {
        this.write(c);
    }

    @Override
    public void print(int i)
    {
        this.write(String.valueOf(i));
    }

    @Override
    public void print(long l)
    {
        this.write(String.valueOf(l));
    }

    @Override
    public void print(float f)
    {
        this.write(String.valueOf(f));
    }

    @Override
    public void print(double d)
    {
        this.write(String.valueOf(d));
    }

    @Override
    public void print(char s[])
    {
        this.write(s);
    }

    @Override
    public void print(String s)
    {
        if (s == null)
            s = "null";
        this.write(s);
    }

    @Override
    public void print(Object obj)
    {
        this.write(String.valueOf(obj));
    }

    @Override
    public void println()
    {
        try
        {
            synchronized (lock)
            {
                isOpen();
                out.write(__lineSeparator);
            }
        }
        catch (InterruptedIOException ex)
        {
            LOG.debug(ex);
            Thread.currentThread().interrupt();
        }
        catch (IOException ex)
        {
            setError(ex);
        }
    }

    @Override
    public void println(boolean b)
    {
        println(b?__trueln:__falseln);
    }

    @Override
    public void println(char c)
    {
        try
        {
            synchronized (lock)
            {
                isOpen();
                out.write(c);
            }
        }
        catch (InterruptedIOException ex)
        {
            LOG.debug(ex);
            Thread.currentThread().interrupt();
        }
        catch (IOException ex)
        {
            setError(ex);
        }
    }

    @Override
    public void println(int x)
    {
        this.println(String.valueOf(x));
    }

    @Override
    public void println(long x)
    {
        this.println(String.valueOf(x));
    }
    
    @Override
    public void println(float x)
    {
        this.println(String.valueOf(x));
    }

    @Override
    public void println(double x)
    {
        this.println(String.valueOf(x));
    }

    @Override
    public void println(char s[])
    {
        try
        {
            synchronized (lock)
            {
                isOpen();
                out.write(s,0,s.length);
                out.write(__lineSeparator);
            }
        }
        catch (InterruptedIOException ex)
        {
            LOG.debug(ex);
            Thread.currentThread().interrupt();
        }
        catch (IOException ex)
        {
            setError(ex);
        }
    }

    @Override
    public void println(String s)
    {
        if (s == null)
            s = "null";
        
        try
        {
            synchronized (lock)
            {
                isOpen();
                out.write(s,0,s.length());
                out.write(__lineSeparator);
            }
        }
        catch (InterruptedIOException ex)
        {
            LOG.debug(ex);
            Thread.currentThread().interrupt();
        }
        catch (IOException ex)
        {
            setError(ex);
        }
    }

    @Override
    public void println(Object x)
    {
        this.println(String.valueOf(x));
    }

    @Override
    public PrintWriter printf(String format, Object... args)
    {
        return format(_locale,format,args);
    }

    @Override
    public PrintWriter printf(Locale l, String format, Object... args)
    {
        return format(l,format,args);
    }

    @Override
    public PrintWriter format(String format, Object... args)
    {
        return format(_locale,format,args);
    }

    @Override
    public PrintWriter format(Locale l, String format, Object... args)
    { 
        try 
        {
            synchronized (lock) 
            {
                isOpen();
                if ((_formatter == null) || (_formatter.locale() != l))
                    _formatter = new Formatter(this, l);
                _formatter.format(l, format, args);
            }
        } 
        catch (InterruptedIOException ex)
        {
            LOG.debug(ex);
            Thread.currentThread().interrupt();
        }
        catch (IOException ex)
        {
            setError(ex);
        }
        return this;
    }

    
    
}