// [SMTPTransportSample.java]
import java.io.*;
import java.util.Date;
import java.net.Socket;

/**
 * 5つのパラメタ(host, from, to, subject, contentFile)を指定して
 * ファイル内容を送信します。
 */
public class SMTPTransportSample {
    public static void main(String[] args) throws Exception {
        sendMessage(args[0], 25, // <- SMTP port
                    args[1], new String[] {args[2]},
                    args[3], args[4]);
    }

    public static void sendMessage(String host, int port,
                                   String from, String[] to,
                                   String subject, String contentFile)
                throws IOException {
        SMTPTransportSample smtp = new SMTPTransportSample(host, port);
        try {
            smtp.sendCommand("HELO " + from.substring(from.indexOf('@') + 1));
            smtp.sendCommand("MAIL FROM:<" + from + '>');

            for (int i = 0; i < to.length; i++) {
                smtp.sendCommand("RCPT TO:<" + to[i] + '>');
            }

            smtp.sendCommand("DATA");
            // contents
            StringBuffer toBuf = new StringBuffer(to[0]);
            for (int i = 1; i < to.length; i++) {
                toBuf.append(", ").append(to[i]);
            }
            smtp.send("To: " + encode(toBuf.toString()));
            smtp.send("From: " + encode(from));
            smtp.send("Subject: " + encode(subject));
            smtp.send("Date: " + getRFC822Date());
            smtp.send("MIME-Version: 1.0");
            smtp.send("Content-Type: text/plain; charset=ISO-2022-JP");
            smtp.send("");

            // read on default encoding
            BufferedReader dataIn =
                    new BufferedReader(new FileReader(contentFile));
            String line;
            while ((line = dataIn.readLine()) != null) {
                smtp.send(line);
            }
            smtp.send(".");
            smtp.checkResponse();

            smtp.sendCommand("QUIT");

            System.out.println("Send complete");
        } finally {
            smtp.close();
        }
    }


    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;
    public SMTPTransportSample(String host, int port) throws IOException {
        try {
            socket = new Socket(host, port);
            in = new BufferedReader(
                    new InputStreamReader(
                        socket.getInputStream()));
            out = new PrintWriter(
                    new OutputStreamWriter(
                        socket.getOutputStream(), "ISO-2022-JP"));

            // skip welcome message
            checkResponse();
        } catch (IOException e) {
            close();
            throw e;
        }
    }

    public void sendCommand(String command) throws IOException {
        send(command);
        checkResponse();
    }

    public void send(String message) {
        System.out.println("S: " + message);
        out.print(message);
        out.print("\r\n");
        out.flush();
    }

    public void checkResponse() throws IOException {
        String response = in.readLine();
        System.out.println("R: " + response);

        if (response.charAt(0) != '2' &&
            response.charAt(0) != '3') {
            throw new IOException(response);
        }
    }

    public void close() {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {}
        }
        if (out != null) {
            out.close();
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {}
        }
    }

    // ヘッダのエンコード処理が入っていませんので、ヘッダに日本語を用いると
    // いわゆる「生JIS」になってしまいます。
    private static String encode(String src) {
        // not implement
        return src;
    }
    // これは正しい形式ではありません。
    private static String getRFC822Date() {
        // not implement
        return new Date().toString();
    }
}

